Merge branch 'master' into develop
diff --git a/.asf.yaml b/.asf.yaml
index 0fe606c..9e79610 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -40,4 +40,4 @@
   features:
     wiki: false
     issues: true
-    projects: true
+    projects: true
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 3b42090..0000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-name: Report a bug
-about: Create a report to help us improve
-labels: bug
-assignees: ''
-
----
-
-<!--
-This form is for bug reports and feature requests ONLY!
-For general questions and troubleshooting about custos, please ask/look for answers here:
-- custos mailing list: https://lists.apache.org/list.html?custos@airavata.apache.org
-
-Issues specific to *airavata*, *airavata-django-portal*, *airavata-mft*, should be created in the repository they belong to (e.g. https://github.com/apache/airavata)
--->
-
-[NOTE]: # ( ^^ Provide a general summary of the issue in the title above. ^^ )
-
-## Description
-
-[NOTE]: # ( Describe the problem you're encountering. )
-
-## Steps to Reproduce
-
-[NOTE]: # ( Include details description or commands to reproduce. )
-
-## Expected Behaviour
-
-[NOTE]: # ( Tell us what you did and what you expected to happen and what you instead saw. )
-
-## Your Environment
-
-[TIP]:  # ( Include as many relevant details about your environment as possible. )
-[TIP]:  # ( Mention Custos Branch or release version, runtime and compiler version )
-
-* Custos branch or release version used:
-* Operating system and version:
-
-## Additional Context
-
-[TIP]:  # ( full error message, exception listing, stack trace, logs or other information which can assist in diagnosing the bug. )
diff --git a/.github/ISSUE_TEMPLATE/cleanup_request.md b/.github/ISSUE_TEMPLATE/cleanup_request.md
deleted file mode 100644
index 7123e8b..0000000
--- a/.github/ISSUE_TEMPLATE/cleanup_request.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-name: Request a cleanup
-about: Suggest a cleanup in custos repository
-labels: cleanup
-assignees: ''
-
----
-
-<!--
-This form is for bug reports and feature requests ONLY!
-For general questions and troubleshooting about custos, please ask/look for answers here:
-- custos mailing list: https://lists.apache.org/list.html?custos@airavata.apache.org
-
-Issues specific to *airavata*, *airavata-django-portal*, *airavata-mft*, should be created in the repository they belong to (e.g. https://github.com/apache/airavata)
--->
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index bbe7c24..0000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-name: Request a feature or enhancement
-about: Suggest an idea for this project
-labels: enhancement
-assignees: ''
-
----
-
-<!--
-This form is for bug reports and feature requests ONLY!
-For general questions and troubleshooting about custos, please ask/look for answers here:
-- custos mailing list: https://lists.apache.org/list.html?custos@airavata.apache.org
-
-Issues specific to *airavata*, *airavata-django-portal*, *airavata-mft*, should be created in the repository they belong to (e.g. https://github.com/apache/airavata)
--->
-
-[NOTE]: # ( ^^ Provide a general summary of the request in the title above. ^^ )
-
-## Is your feature request related to a problem? Please describe.
-A clear and concise description of what the problem is. 
-
-## Describe the solution you'd like
-A clear and concise description of what you want to happen.
-
-## Describe alternatives you've considered
-A clear and concise description of any alternative solutions or features you've considered.
-
-## Additional context
-[TIP]:  # ( Why does this feature matter to you? What unique use cases do you have? )
-Add any other context about the feature request here.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 2925d11..0000000
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,39 +0,0 @@
-<!-- Thank you for your contribution to Apache Airavata!
-
-     Please file this form by replacing the Markdown comments
-     with your text. If a section needs no action - remove it.
-
-     Also remember, that Airavata uses the Review-Then-Commit (RTC) model
-     of code collaboration. Positive feedback is represented +1 from committers
-     and negative is a -1. The -1 also means veto, and needs to be addressed
-     to proceed. Once there are no objections, the PR can be merged by a
-     airavata committer.
--->
-## Overview
-<!--- Provide a concise summary of your changes in the Title -->
-
-## Description
-<!--- Provide a detailed description of your changes. -->
-<!--- Include details of what problem you are solving-->
-
-## Testing recommendations
-
-<!-- Describe how we can test your changes.
-     Does it provides any behaviour that the end users
-     could notice? -->
-
-## Related Issues or Pull Requests
-
-<!-- If your changes affects multiple components in different
-     repositories please put links to those issues or pull requests here.  -->
-     
-## Types of changes
-<!--- What types of changes does your code introduce? Use `x` in all the boxes that apply: -->
-- [ ] Bug fix (generally a non-breaking change which closes an issue).
-- [ ] Enhancement or new feature (adds new functionality).
-- [ ] Breaking change (a bug fix or enhancement which changes existing behavior).
-
-## Checklist
-
-- [ ] Code is written and works correctly
-- [ ] Changes are covered by tests
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 0bf1c28..78c1f0f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,7 +40,3 @@
 dist/
 
 database_data
-.idea/*
-*.iml
-target/*
-.vscode
diff --git a/.travis.yml b/.travis.yml
index 21894a5..17d1570 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,4 @@
 #
-#
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -34,4 +33,4 @@
 
 # Git-describe Maven plugin needs the full history
 git:
-  depth: false
+  depth: false
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7a4a3ea
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d8f16ee
--- /dev/null
+++ b/README.md
@@ -0,0 +1,39 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+# Apache Airavata Custos Security
+
+[![License](http://img.shields.io/badge/license-Apache--2-blue.svg?style=flat)](https://apache.org/licenses/LICENSE-2.0)
+[![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed/apache/airavata-custos)](https://github.com/apache/airavata-custos/pulls?q=is%3Apr+is%3Aclosed)
+[![Build Status](https://travis-ci.org/apache/airavata-custos.png?branch=develop)](https://travis-ci.org/github/apache/airavata-custos)
+
+Science gateways represent potential targets for cybersecurity threats to users, scientific research, and scientific resources. Custos is a software framework that provides common security operations for science gateways, including user identity and access management, gateway tenant profile management, resource secrets management, and groups and sharing management. The goals of the Custos project are to provide these services to a wide range of science gateway frameworks, providing the community with an open-source, transparent, and reviewed code base for common security operations; and to operate trustworthy security services for the science gateway community using this software base. To accomplish these goals, we implement Custos using a scalable microservice architecture that can provide highly available, fault-tolerant operations. Custos exposes these services through a language-independent Application Programming Interface that encapsulates science gateway usage scenarios.
+
+**To find out more, please check out the [Custos website](https://airavata.apache.org/custos/) and the [Custos wiki](https://cwiki.apache.org/confluence/display/CUSTOS/Home).**
+
+## Quickstart
+
+## Installation Instructions
+
+## Roadmap
+
+## Contributing
+
+## Questions or need help?
+
diff --git a/custos-client-sdks/custos-java-clients/agent-management-client/pom.xml b/custos-client-sdks/custos-java-clients/agent-management-client/pom.xml
new file mode 100644
index 0000000..91587f8
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/agent-management-client/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-java-clients</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>agent-management-client</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>agent-management-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-clients-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>
+                        ../../../custos-integration-services/agent-management-service-parent/agent-management-service/src/main/proto
+                    </protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-java-clients/agent-management-client/src/main/java/org/apache/custos/agent/management/client/AgentManagementClient.java b/custos-client-sdks/custos-java-clients/agent-management-client/src/main/java/org/apache/custos/agent/management/client/AgentManagementClient.java
new file mode 100644
index 0000000..e5a996d
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/agent-management-client/src/main/java/org/apache/custos/agent/management/client/AgentManagementClient.java
@@ -0,0 +1,328 @@
+package org.apache.custos.agent.management.client;
+
+import io.grpc.ManagedChannel;
+import io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.NettyChannelBuilder;
+import io.grpc.stub.MetadataUtils;
+import org.apache.custos.agent.management.service.AgentManagementServiceGrpc;
+import org.apache.custos.agent.management.service.AgentRegistrationResponse;
+import org.apache.custos.agent.management.service.AgentSearchRequest;
+import org.apache.custos.clients.core.ClientUtils;
+import org.apache.custos.iam.service.*;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * This class contains methods of Agent Management
+ */
+public class AgentManagementClient {
+
+    private ManagedChannel managedChannel;
+
+    private AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub;
+
+
+    public AgentManagementClient(String serviceHost, int servicePort, String clientId,
+                                 String clientSecret) throws IOException {
+
+        managedChannel = NettyChannelBuilder.forAddress(serviceHost, servicePort)
+                .sslContext(GrpcSslContexts
+                        .forClient()
+                        .trustManager(ClientUtils.getServerCertificate(serviceHost, clientId, clientSecret)) // public key
+                        .build())
+                .build();
+
+        blockingStub = AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        blockingStub = MetadataUtils.attachHeaders(blockingStub, ClientUtils.getAuthorizationHeader(clientId, clientSecret));
+    }
+
+
+    /**
+     * Enable agents, this is should be the first operation to enable agent functions
+     * @param adminToken
+     * @return
+     */
+    public OperationStatus enableAgents(String adminToken) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AgentClientMetadata metadata = AgentClientMetadata
+                .newBuilder()
+                .build();
+
+        return blockingStub.enableAgents(metadata);
+    }
+
+
+    /**
+     * Sets access token life time
+     * @param adminToken
+     * @param accessTokenLifeTime
+     * @return
+     */
+    public OperationStatus configureAgentClient(String adminToken, long accessTokenLifeTime) {
+
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AgentClientMetadata metadata = AgentClientMetadata
+                .newBuilder()
+                .setAccessTokenLifeTime(accessTokenLifeTime)
+                .build();
+
+        return blockingStub.configureAgentClient(metadata);
+    }
+
+    /**
+     * This will register agent and activate agent
+     * @param adminToken
+     * @param id
+     * @param realmRoles
+     * @param agentAttributes
+     * @return
+     */
+    public AgentRegistrationResponse registerAndEnableAgent(String adminToken, String id, String[] realmRoles, UserAttribute[] agentAttributes) {
+
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        UserRepresentation userRepresentation = UserRepresentation
+                .newBuilder()
+                .setId(id)
+                .addAllRealmRoles(Arrays.asList(realmRoles))
+                .addAllAttributes(Arrays.asList(agentAttributes))
+                .build();
+
+        RegisterUserRequest userRequest = RegisterUserRequest
+                .newBuilder()
+                .setUser(userRepresentation)
+                .build();
+
+        return blockingStub.registerAndEnableAgent(userRequest);
+
+    }
+
+
+    /**
+     * Get agent
+     * @param adminToken
+     * @param agentId
+     * @return
+     */
+    public Agent getAgent(String adminToken, String agentId) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AgentSearchRequest request = AgentSearchRequest
+                .newBuilder()
+                .setId(agentId)
+                .build();
+
+        return blockingStub.getAgent(request);
+    }
+
+    /**
+     * Delete agent
+     * @param adminToken
+     * @param agentId
+     * @return
+     */
+    public OperationStatus deleteAgent(String adminToken, String agentId) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AgentSearchRequest request = AgentSearchRequest
+                .newBuilder()
+                .setId(agentId)
+                .build();
+
+        return blockingStub.deleteAgent(request);
+    }
+
+
+    /**
+     * Disable agent
+     * @param adminToken
+     * @param agentId
+     * @return
+     */
+    public OperationStatus disableAgent(String adminToken, String agentId) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AgentSearchRequest request = AgentSearchRequest
+                .newBuilder()
+                .setId(agentId)
+                .build();
+
+        return blockingStub.disableAgent(request);
+
+    }
+
+
+    /**
+     * Enable agent
+     * @param adminToken
+     * @param agentId
+     * @return
+     */
+    public OperationStatus enableAgent(String adminToken, String agentId) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AgentSearchRequest request = AgentSearchRequest
+                .newBuilder()
+                .setId(agentId)
+                .build();
+
+        return blockingStub.enableAgent(request);
+    }
+
+
+    /**
+     * Add agent attributes
+     * @param adminToken
+     * @param agents
+     * @param attributes
+     * @return
+     */
+    public OperationStatus addAgentAttributes(String adminToken, String[] agents, UserAttribute[] attributes) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+        AddUserAttributesRequest addUserAttributesRequest = AddUserAttributesRequest
+                .newBuilder()
+                .addAllAttributes(Arrays.asList(attributes))
+                .addAllAgents(Arrays.asList(agents))
+                .build();
+        return blockingStub.addAgentAttributes(addUserAttributesRequest);
+
+    }
+
+
+    /**
+     * Delete agent attributes
+     * @param adminToken
+     * @param agents
+     * @param attributes
+     * @return
+     */
+    public OperationStatus deleteAgentAttributes(String adminToken, String[] agents, UserAttribute[] attributes) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        DeleteUserAttributeRequest addUserAttributesRequest = DeleteUserAttributeRequest
+                .newBuilder()
+                .addAllAttributes(Arrays.asList(attributes))
+                .addAllAgents(Arrays.asList(agents))
+                .build();
+        return blockingStub.deleteAgentAttributes(addUserAttributesRequest);
+    }
+
+
+    /**
+     * Add roles to agents
+     * @param adminToken
+     * @param agents
+     * @param roles
+     * @return
+     */
+    public OperationStatus addRolesToAgents(String adminToken, String[] agents, String[] roles) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AddUserRolesRequest addUserRolesRequest = AddUserRolesRequest
+                .newBuilder()
+                .addAllAgents(Arrays.asList(agents))
+                .addAllRoles(Arrays.asList(roles))
+                .build();
+        return blockingStub.addRolesToAgent(addUserRolesRequest);
+
+    }
+
+
+    /**
+     * Delete roles from agents
+     * @param adminToken
+     * @param id
+     * @param roles
+     * @return
+     */
+    public OperationStatus deleteRolesFromAgents(String adminToken, String id, String[] roles) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        DeleteUserRolesRequest deleteUserRolesRequest = DeleteUserRolesRequest
+                .newBuilder()
+                .addAllRoles(Arrays.asList(roles))
+                .setId(id)
+                .build();
+        return blockingStub.deleteRolesFromAgent(deleteUserRolesRequest);
+
+    }
+
+    /**
+     * Add protocol mapper, this will add attributes and roles to token
+     * @param adminToken
+     * @param name
+     * @param attributeName
+     * @param claimName
+     * @param claimType
+     * @param mapperType
+     * @param addToIdToken
+     * @param addToAccessToken
+     * @param addToUserInfo
+     * @param multiValued
+     * @param aggregrateAttributeValues
+     * @return
+     */
+    public OperationStatus addProtocolMapper(String adminToken, String name, String attributeName, String claimName, String claimType, String mapperType,
+                                             boolean addToIdToken, boolean addToAccessToken, boolean addToUserInfo, boolean multiValued,
+                                             boolean aggregrateAttributeValues) {
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub unAuthorizedStub =
+                AgentManagementServiceGrpc.newBlockingStub(managedChannel);
+        AgentManagementServiceGrpc.AgentManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AddProtocolMapperRequest mapperRequest = AddProtocolMapperRequest
+                .newBuilder()
+                .setName(name)
+                .setAttributeName(attributeName)
+                .setClaimName(claimName)
+                .setClaimType(ClaimJSONTypes.valueOf(claimType))
+                .setMapperType(MapperTypes.valueOf(mapperType))
+                .setAddToIdToken(addToIdToken)
+                .setAddToAccessToken(addToAccessToken)
+                .setAddToUserInfo(addToUserInfo)
+                .setMultiValued(multiValued)
+                .setAggregateAttributeValues(aggregrateAttributeValues)
+                .build();
+        return blockingStub.addProtocolMapper(mapperRequest);
+
+
+    }
+
+
+}
diff --git a/custos-client-sdks/custos-java-clients/custos-clients-core/pom.xml b/custos-client-sdks/custos-java-clients/custos-clients-core/pom.xml
new file mode 100644
index 0000000..156ea75
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/custos-clients-core/pom.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-java-clients</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-clients-core</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-java-clients/custos-clients-core/src/main/java/org/apache/custos/clients/core/ClientUtils.java b/custos-client-sdks/custos-java-clients/custos-clients-core/src/main/java/org/apache/custos/clients/core/ClientUtils.java
new file mode 100644
index 0000000..2bd9c6a
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/custos-clients-core/src/main/java/org/apache/custos/clients/core/ClientUtils.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.clients.core;
+
+import io.grpc.Metadata;
+import org.apache.custos.integration.core.utils.Constants;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Base64;
+
+
+/**
+ * Utility methods for clients
+ */
+public class ClientUtils {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientUtils.class);
+
+    /**
+     * Creates authorization header
+     *
+     * @param clientId
+     * @param clientSecret
+     * @return
+     */
+    public static Metadata getAuthorizationHeader(String clientId, String clientSecret) {
+
+        String credential = clientId + ":" + clientSecret;
+
+        byte[] token = Base64.getEncoder().encode(credential.getBytes());
+
+        String formattedString = new String(token);
+        String headerStr = "Bearer " + formattedString;
+        Metadata header = new Metadata();
+        Metadata.Key<String> key = Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER);
+        header.put(key, headerStr);
+        return header;
+    }
+
+
+    public static Metadata getAuthorizationHeader(String accessToken) {
+
+        String headerStr = "Bearer " + accessToken;
+        Metadata header = new Metadata();
+        Metadata.Key<String> key = Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER);
+        header.put(key, headerStr);
+        return header;
+    }
+
+
+    public static Metadata getUserTokenHeader(String accessToken) {
+        Metadata header = new Metadata();
+        Metadata.Key<String> key = Metadata.Key.of(Constants.USER_TOKEN, Metadata.ASCII_STRING_MARSHALLER);
+        header.put(key, accessToken);
+        return header;
+    }
+
+    /**
+     * Provides file object
+     *
+     * @param classObj
+     * @param fileName
+     * @return
+     */
+    public static File getFile(Class classObj, final String fileName) {
+        return new File(classObj
+                .getResource(fileName)
+                .getFile());
+    }
+
+
+    public static InputStream getServerCertificate(String serverHost, String clientId,
+                                                   String clientSec) throws IOException {
+        HttpURLConnection conn = null;
+        InputStream inputStream = null;
+        try {
+            String url = "https://" + serverHost +
+                    "/apiserver/resource-secret-management/v1.0.0/secret?metadata.owner_type=CUSTOS&metadata.resource_type=SERVER_CERTIFICATE";
+
+            URL endpoint = new URL(url);
+            conn = (HttpURLConnection) endpoint.openConnection();
+            conn.setRequestMethod("GET");
+            String userCredentials = clientId + ":" + clientSec;
+            String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
+            conn.setRequestProperty("Accept", "application/json");
+            conn.setRequestProperty("Authorization", basicAuth);
+            if (conn.getResponseCode() != 200) {
+                throw new RuntimeException("Failed : HTTP error code : "
+                        + conn.getResponseCode());
+            }
+
+            StringBuilder responseStrBuilder = new StringBuilder();
+            inputStream = conn.getInputStream();
+            BufferedReader br = new BufferedReader(new InputStreamReader(
+                    (inputStream)));
+
+            String output;
+
+            while ((output = br.readLine()) != null) {
+                responseStrBuilder.append(output);
+            }
+
+            JSONObject jsonObject = new JSONObject(responseStrBuilder.toString());
+
+            Object key = jsonObject.get("value");
+            return new ByteArrayInputStream(((String) key).getBytes(Charset.forName("UTF-8")));
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching server certificate";
+            LOGGER.error(msg, ex);
+            throw ex;
+        } finally {
+            if (conn != null) {
+                conn.disconnect();
+                inputStream.close();
+
+            }
+        }
+
+    }
+
+}
diff --git a/custos-client-sdks/custos-java-clients/group-management-client/pom.xml b/custos-client-sdks/custos-java-clients/group-management-client/pom.xml
new file mode 100644
index 0000000..9a5c1f0
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/group-management-client/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-java-clients</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>group-management-client</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>group-management-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-clients-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>
+                        ../../../custos-integration-services/group-management-service-parent/group-management-service/src/main/proto
+                    </protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-java-clients/group-management-client/src/main/java/org/apache/custos/group/management/client/GroupManagementClient.java b/custos-client-sdks/custos-java-clients/group-management-client/src/main/java/org/apache/custos/group/management/client/GroupManagementClient.java
new file mode 100644
index 0000000..eaa0ca9
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/group-management-client/src/main/java/org/apache/custos/group/management/client/GroupManagementClient.java
@@ -0,0 +1,295 @@
+package org.apache.custos.group.management.client;
+
+import io.grpc.ManagedChannel;
+import io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.NettyChannelBuilder;
+import io.grpc.stub.MetadataUtils;
+import org.apache.custos.clients.core.ClientUtils;
+import org.apache.custos.group.management.service.GroupManagementServiceGrpc;
+import org.apache.custos.iam.service.GroupRequest;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.user.profile.service.*;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * This contains group management related functions
+ */
+public class GroupManagementClient {
+
+    private ManagedChannel managedChannel;
+
+    private GroupManagementServiceGrpc.GroupManagementServiceBlockingStub blockingStub;
+
+
+    public GroupManagementClient(String serviceHost, int servicePort, String clientId,
+                                 String clientSecret) throws IOException {
+
+        managedChannel = NettyChannelBuilder.forAddress(serviceHost, servicePort)
+                .sslContext(GrpcSslContexts
+                        .forClient()
+                        .trustManager(ClientUtils.getServerCertificate(serviceHost, clientId, clientSecret)) // public key
+                        .build())
+                .build();
+
+        blockingStub = GroupManagementServiceGrpc.newBlockingStub(managedChannel);
+        blockingStub = MetadataUtils.attachHeaders(blockingStub, ClientUtils.getAuthorizationHeader(clientId, clientSecret));
+    }
+
+
+    /**
+     * Create groups
+     *
+     * @param clientId
+     * @param groupRepresentation
+     * @return
+     */
+    public GroupsResponse createGroup(String clientId, GroupRepresentation[] groupRepresentation) {
+
+        GroupsRequest request = GroupsRequest
+                .newBuilder()
+                .addAllGroups(Arrays.asList(groupRepresentation))
+                .setClientId(clientId)
+                .build();
+        return blockingStub.createGroups(request);
+
+    }
+
+
+    /**
+     * update group
+     *
+     * @param clientId
+     * @param groupRepresentation
+     * @return
+     */
+    public GroupRepresentation updateGroup(String clientId, GroupRepresentation groupRepresentation) {
+
+        GroupRequest request = GroupRequest
+                .newBuilder()
+                .setGroup(groupRepresentation)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.updateGroup(request);
+    }
+
+    /**
+     * delete group
+     *
+     * @param clientId
+     * @param groupRepresentation
+     * @return
+     */
+    public OperationStatus deleteGroup(String clientId, GroupRepresentation groupRepresentation) {
+
+        GroupRequest request = GroupRequest
+                .newBuilder()
+                .setGroup(groupRepresentation)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.deleteGroup(request);
+    }
+
+
+    /**
+     * find group
+     *
+     * @param clientId
+     * @param groupName
+     * @param groupId
+     * @return
+     */
+    public GroupRepresentation findGroup(String clientId, String groupName, String groupId) {
+
+        GroupRepresentation groupRepresentation =
+                GroupRepresentation.newBuilder().build();
+        if (groupName != null) {
+            groupRepresentation = groupRepresentation.toBuilder().setName(groupName).build();
+        }
+
+        if (groupId != null) {
+            groupRepresentation = groupRepresentation.toBuilder().setId(groupId).build();
+        }
+
+        GroupRequest request = GroupRequest
+                .newBuilder()
+                .setGroup(groupRepresentation)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.findGroup(request);
+    }
+
+
+    /**
+     * Get all groups
+     *
+     * @param clientId
+     * @return
+     */
+    public GroupsResponse getAllGroups(String clientId) {
+        GroupRequest request = GroupRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .build();
+        return blockingStub.getAllGroups(request);
+    }
+
+
+    /**
+     * Add user to group
+     *
+     * @param clientId
+     * @param username
+     * @param groupId
+     * @return
+     */
+    public OperationStatus addUserToGroup(String clientId, String username, String groupId, String type) {
+        UserGroupMappingRequest request = UserGroupMappingRequest
+                .newBuilder()
+                .setUsername(username)
+                .setClientId(clientId)
+                .setMembershipType(type)
+                .setGroupId(groupId).build();
+        return blockingStub.addUserToGroup(request);
+
+    }
+
+    /**
+     * Remove user from group
+     *
+     * @param clientId
+     * @param username
+     * @param groupId
+     * @return
+     */
+    public OperationStatus removeUserFromGroup(String clientId, String username, String groupId) {
+
+        UserGroupMappingRequest request = UserGroupMappingRequest
+                .newBuilder()
+                .setUsername(username)
+                .setClientId(clientId)
+                .setGroupId(groupId).build();
+        return blockingStub.removeUserFromGroup(request);
+
+    }
+
+
+    public OperationStatus addChildGroupToParentGroup(String clientId, String parentId, String childId) {
+        GroupToGroupMembership membership = GroupToGroupMembership
+                .newBuilder()
+                .setChildId(childId)
+                .setParentId(parentId)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.addChildGroupToParentGroup(membership);
+    }
+
+
+    public OperationStatus removeChildGroupFromParentGroup(String clientId, String parentId, String childId) {
+        GroupToGroupMembership membership = GroupToGroupMembership
+                .newBuilder()
+                .setChildId(childId)
+                .setParentId(parentId)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.removeChildGroupFromParentGroup(membership);
+    }
+
+
+    public GetAllGroupsResponse getAllGroupsOfUser(String clientId, String username) {
+        UserProfile userProfile = UserProfile
+                .newBuilder()
+                .setUsername(username)
+                .build();
+        UserProfileRequest userProfileRequest = UserProfileRequest
+                .newBuilder()
+                .setProfile(userProfile)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.getAllGroupsOfUser(userProfileRequest);
+    }
+
+
+    public GetAllGroupsResponse getAllParentGroupsOfGroup(String clientId, String id) {
+        Group group = Group
+                .newBuilder()
+                .setId(id)
+                .build();
+
+        org.apache.custos.user.profile.service.GroupRequest request =
+                org.apache.custos.user.profile.service.GroupRequest
+                        .newBuilder()
+                        .setGroup(group)
+                        .setClientId(clientId)
+                        .build();
+
+        return blockingStub.getAllParentGroupsOfGroup(request);
+    }
+
+
+    public GetAllUserProfilesResponse getAllChildUsers(String clientId, String id) {
+        Group group = Group
+                .newBuilder()
+                .setId(id)
+                .build();
+
+        org.apache.custos.user.profile.service.GroupRequest request =
+                org.apache.custos.user.profile.service.GroupRequest
+                        .newBuilder()
+                        .setGroup(group)
+                        .setClientId(clientId)
+                        .build();
+
+        return blockingStub.getAllChildUsers(request);
+    }
+
+
+    public GetAllGroupsResponse getAllChildGroups(String clientId, String id) {
+        Group group = Group
+                .newBuilder()
+                .setId(id)
+                .build();
+
+        org.apache.custos.user.profile.service.GroupRequest request =
+                org.apache.custos.user.profile.service.GroupRequest
+                        .newBuilder()
+                        .setGroup(group)
+                        .setClientId(clientId)
+                        .build();
+
+        return blockingStub.getAllChildGroups(request);
+    }
+
+
+    public OperationStatus changeUserMembershipType(String clientId, String username, String groupId, String type) {
+
+        GroupMembership membership = GroupMembership
+                .newBuilder()
+                .setUsername(username)
+                .setGroupId(groupId)
+                .setType(type)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.changeUserMembershipType(membership);
+    }
+
+
+    public OperationStatus hasAccess(String clientId, String groupId, String userId, String type) {
+        GroupMembership membership = GroupMembership
+                .newBuilder()
+                .setUsername(userId)
+                .setGroupId(groupId)
+                .setType(type)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.hasAccess(membership);
+
+    }
+
+}
diff --git a/custos-client-sdks/custos-java-clients/identity-management-client/pom.xml b/custos-client-sdks/custos-java-clients/identity-management-client/pom.xml
new file mode 100644
index 0000000..96546d1
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/identity-management-client/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-java-clients</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>identity-management-client</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-management-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-clients-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../../custos-integration-services/identity-management-service-parent/identity-management-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+
+
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-java-clients/identity-management-client/src/main/java/org/apache/custos/identity/management/client/IdentityManagementClient.java b/custos-client-sdks/custos-java-clients/identity-management-client/src/main/java/org/apache/custos/identity/management/client/IdentityManagementClient.java
new file mode 100644
index 0000000..c8fe1b9
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/identity-management-client/src/main/java/org/apache/custos/identity/management/client/IdentityManagementClient.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.management.client;
+
+import com.google.protobuf.Struct;
+import io.grpc.ManagedChannel;
+import io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.NettyChannelBuilder;
+import io.grpc.stub.MetadataUtils;
+import org.apache.custos.clients.core.ClientUtils;
+import org.apache.custos.credential.store.service.Credentials;
+import org.apache.custos.identity.management.service.GetAgentTokenRequest;
+import org.apache.custos.identity.management.service.GetCredentialsRequest;
+import org.apache.custos.identity.management.service.IdentityManagementServiceGrpc;
+import org.apache.custos.identity.service.*;
+
+import java.io.IOException;
+
+/**
+ * Java client to connect with the Custos Identity Management Service
+ */
+public class IdentityManagementClient {
+
+
+    private ManagedChannel managedChannel;
+
+    private IdentityManagementServiceGrpc.IdentityManagementServiceBlockingStub blockingStub;
+
+    private IdentityManagementServiceGrpc.IdentityManagementServiceBlockingStub cleanBlockingStub;
+
+
+    public IdentityManagementClient(String serviceHost, int servicePort, String clientId,
+                                    String clientSecret) throws IOException {
+
+        managedChannel = NettyChannelBuilder.forAddress(serviceHost, servicePort)
+                .sslContext(GrpcSslContexts
+                        .forClient()
+                        .trustManager(ClientUtils.getServerCertificate(serviceHost, clientId, clientSecret)) // public key
+                        .build())
+                .build();
+
+        blockingStub = IdentityManagementServiceGrpc.newBlockingStub(managedChannel);
+        cleanBlockingStub = IdentityManagementServiceGrpc.newBlockingStub(managedChannel);
+        blockingStub = MetadataUtils.attachHeaders(blockingStub, ClientUtils.getAuthorizationHeader(clientId, clientSecret));
+    }
+
+
+    /**
+     * Get token
+     *
+     * @param redirectUri
+     * @param code
+     * @param username
+     * @param password
+     * @param refreshToken
+     * @param grantType
+     * @return
+     */
+    public Struct getToken(String redirectUri, String code, String username, String password, String refreshToken,
+                           String grantType) {
+
+        GetTokenRequest.Builder request = GetTokenRequest.newBuilder();
+
+        if (redirectUri != null) {
+            request = request.setRedirectUri(redirectUri);
+        }
+
+        if (code != null) {
+            request = request.setCode(code);
+        }
+        if (username != null) {
+            request = request.setUsername(username);
+        }
+        if (password != null) {
+            request = request.setPassword(password);
+        }
+        if (refreshToken != null) {
+            request = request.setRefreshToken(refreshToken);
+        }
+        if (grantType != null) {
+            request = request.setGrantType(grantType);
+        }
+
+        return blockingStub.token(request.build());
+
+    }
+
+
+    /**
+     * Get iam, cilogon credentials of given tenant
+     *
+     * @param clientId
+     * @return
+     */
+    public Credentials getCredentials(String clientId) {
+        GetCredentialsRequest request = GetCredentialsRequest.newBuilder().setClientId(clientId).build();
+        return blockingStub.getCredentials(request);
+    }
+
+
+    /**
+     * Get OIDC configurations of given client
+     *
+     * @param clientId
+     * @return
+     */
+    public Struct getOIDCConfiguration(String clientId) {
+
+        GetOIDCConfiguration configuration = GetOIDCConfiguration
+                .newBuilder()
+                .setClientId(clientId).build();
+        return blockingStub.getOIDCConfiguration(configuration);
+
+    }
+
+
+    /**
+     * End user session
+     *
+     * @param refreshToken
+     * @return
+     */
+    public OperationStatus endUserSession(String refreshToken) {
+        EndSessionRequest body = EndSessionRequest
+                .newBuilder()
+                .setRefreshToken(refreshToken)
+                .build();
+        org.apache.custos.identity.management.service.EndSessionRequest endSessionRequest =
+                org.apache.custos.identity.management.service.EndSessionRequest
+                        .newBuilder()
+                        .setBody(body)
+                        .build();
+        return blockingStub.endUserSession(endSessionRequest);
+    }
+
+
+    /**
+     * Get agent tokens
+     *
+     * @param clientId
+     * @param grantType
+     * @param refreshToken
+     * @return
+     */
+    public Struct getAgentToken(String clientId, String agentId, String agentSec, String grantType, String refreshToken) {
+
+        GetAgentTokenRequest.Builder agentTokenRequest = GetAgentTokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setGrantType(grantType);
+
+        if (refreshToken != null) {
+            agentTokenRequest = agentTokenRequest.setRefreshToken(refreshToken);
+        }
+
+        cleanBlockingStub = MetadataUtils.attachHeaders(cleanBlockingStub, ClientUtils.getAuthorizationHeader(agentId, agentSec));
+        return cleanBlockingStub.getAgentToken(agentTokenRequest.build());
+
+    }
+
+    public User getUser(String clientId, String username, String accessToken) {
+
+        Claim user = Claim.newBuilder().setKey("username").setValue(username).build();
+        Claim cli = Claim.newBuilder().setKey("client_id").setValue(clientId).build();
+
+        AuthToken authToken = AuthToken.newBuilder()
+                .setAccessToken(accessToken)
+                .addClaims(user)
+                .addClaims(cli)
+                .build();
+        return blockingStub.getUser(authToken);
+
+    }
+
+
+}
diff --git a/custos-client-sdks/custos-java-clients/pom.xml b/custos-client-sdks/custos-java-clients/pom.xml
new file mode 100644
index 0000000..39af75f
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-client-sdks</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>custos-java-clients</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>identity-management-client</module>
+        <module>tenant-management-client</module>
+        <module>custos-clients-core</module>
+        <module>user-management-client</module>
+        <module>agent-management-client</module>
+        <module>group-management-client</module>
+        <module>resource-secret-management-client</module>
+        <module>sharing-management-client</module>
+    </modules>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-java-clients/resource-secret-management-client/pom.xml b/custos-client-sdks/custos-java-clients/resource-secret-management-client/pom.xml
new file mode 100644
index 0000000..f6b1ac5
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/resource-secret-management-client/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-java-clients</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>resource-secret-management-client</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>resource-secret-management-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-clients-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>
+                        ../../../custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/proto
+                    </protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-java-clients/resource-secret-management-client/src/main/java/org/apache/custos/resource/secret/management/client/ResourceSecretManagementClient.java b/custos-client-sdks/custos-java-clients/resource-secret-management-client/src/main/java/org/apache/custos/resource/secret/management/client/ResourceSecretManagementClient.java
new file mode 100644
index 0000000..a43639a
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/resource-secret-management-client/src/main/java/org/apache/custos/resource/secret/management/client/ResourceSecretManagementClient.java
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.management.client;
+
+import com.google.protobuf.Struct;
+import io.grpc.ManagedChannel;
+import io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.NettyChannelBuilder;
+import io.grpc.stub.MetadataUtils;
+import org.apache.custos.clients.core.ClientUtils;
+import org.apache.custos.identity.service.GetJWKSRequest;
+import org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceGrpc;
+import org.apache.custos.resource.secret.service.*;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * This class is responsible for managing resource secrets
+ */
+public class ResourceSecretManagementClient {
+
+    private ManagedChannel managedChannel;
+
+    private ResourceSecretManagementServiceGrpc.ResourceSecretManagementServiceBlockingStub blockingStub;
+
+
+    public ResourceSecretManagementClient(String serviceHost, int servicePort, String clientId,
+                                          String clientSecret) throws IOException {
+
+        managedChannel = NettyChannelBuilder.forAddress(serviceHost, servicePort)
+                .sslContext(GrpcSslContexts
+                        .forClient()
+                        .trustManager(ClientUtils.getServerCertificate(serviceHost, clientId, clientSecret)) // public key
+                        .build())
+                .build();
+
+        blockingStub = ResourceSecretManagementServiceGrpc.newBlockingStub(managedChannel);
+
+        blockingStub = MetadataUtils.attachHeaders(blockingStub,
+                ClientUtils.getAuthorizationHeader(clientId, clientSecret));
+
+    }
+
+
+    /**
+     * provides resource secret for given owner type and resource type
+     *
+     * @param ownerType
+     * @param resourceType
+     * @return
+     */
+    public SecretMetadata getSecret(ResourceOwnerType ownerType, ResourceType resourceType) {
+
+        SecretMetadata metadata = SecretMetadata
+                .newBuilder()
+                .setOwnerType(ownerType)
+                .setResourceType(resourceType)
+                .build();
+
+        GetSecretRequest request = GetSecretRequest.newBuilder().setMetadata(metadata).build();
+        return blockingStub.getSecret(request);
+    }
+
+    /**
+     * provides JWKS keys for calling tenant
+     *
+     * @return
+     */
+    public Struct getJWKS() {
+        GetJWKSRequest request = GetJWKSRequest.newBuilder().build();
+        return blockingStub.getJWKS(request);
+    }
+
+
+    /**
+     * Provides metadata object of credentials
+     *
+     * @param clientId
+     * @param token
+     * @return SecretMetadata
+     */
+    public SecretMetadata getResourceCredentialSummary(String clientId, String token) {
+
+        GetResourceCredentialByTokenRequest tokenRequest = GetResourceCredentialByTokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setToken(token)
+                .build();
+
+        return blockingStub.getResourceCredentialSummary(tokenRequest);
+
+    }
+
+    /**
+     * Provides metadata array of credentials metadata
+     *
+     * @param clientId
+     * @param accessibleTokens
+     * @return SecretMetadata[]
+     */
+    public ResourceCredentialSummaries getAllResourceCredentialSummaries(String clientId, List<String> accessibleTokens) {
+        GetResourceCredentialSummariesRequest summariesRequest = GetResourceCredentialSummariesRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .addAllAccessibleTokens(accessibleTokens).build();
+
+
+        return blockingStub.getAllResourceCredentialSummaries(summariesRequest);
+
+    }
+
+    /**
+     * Generate SSH credentials
+     *
+     * @param clientId
+     * @param description
+     * @param ownerId
+     * @return AddResourceCredentialResponse
+     */
+    public AddResourceCredentialResponse generateSSHCredential(String clientId, String description, String ownerId) {
+
+        SecretMetadata metadata = SecretMetadata.newBuilder()
+                .setClientId(clientId)
+                .setDescription(description)
+                .setOwnerId(ownerId).build();
+
+
+        SSHCredential sshCredential = SSHCredential
+                .newBuilder()
+                .setMetadata(metadata).build();
+
+        return blockingStub.addSSHCredential(sshCredential);
+
+    }
+
+    /**
+     * Save password credentials
+     *
+     * @param clientId
+     * @param description
+     * @param ownerId
+     * @param password
+     * @return AddResourceCredentialResponse
+     */
+    public AddResourceCredentialResponse addPasswordCredential(String clientId, String description, String ownerId, String password) {
+        SecretMetadata metadata = SecretMetadata.newBuilder()
+                .setClientId(clientId)
+                .setDescription(description)
+                .setOwnerId(ownerId).build();
+
+
+        PasswordCredential sshCredential = PasswordCredential
+                .newBuilder()
+                .setMetadata(metadata)
+                .setPassword(password)
+                .build();
+
+        return blockingStub.addPasswordCredential(sshCredential);
+
+    }
+
+
+    /**
+     * Provides SSHCredential of given token
+     *
+     * @param clientId
+     * @param token
+     * @return SSHCredential
+     */
+    public SSHCredential getSSHCredential(String clientId, String token) {
+        GetResourceCredentialByTokenRequest tokenRequest = GetResourceCredentialByTokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setToken(token)
+                .build();
+
+
+        return blockingStub.getSSHCredential(tokenRequest);
+
+    }
+
+    /**
+     * provides PasswordCredential of given token
+     *
+     * @param clientId
+     * @param token
+     * @return PasswordCredential
+     */
+    public PasswordCredential getPasswordCredential(String clientId, String token) {
+
+        GetResourceCredentialByTokenRequest tokenRequest = GetResourceCredentialByTokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setToken(token)
+                .build();
+
+
+        return blockingStub.getPasswordCredential(tokenRequest);
+    }
+
+
+    /**
+     * Delete SSHCredential of given token
+     *
+     * @param clientId
+     * @param token
+     * @return ResourceCredentialOperationStatus
+     */
+    public ResourceCredentialOperationStatus deleteSSHCredential(String clientId, String token) {
+        GetResourceCredentialByTokenRequest tokenRequest = GetResourceCredentialByTokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setToken(token)
+                .build();
+
+        return blockingStub.deleteSSHCredential(tokenRequest);
+    }
+
+
+    /**
+     * Delete Password Credential of given token
+     *
+     * @param clientId
+     * @param token
+     * @return ResourceCredentialOperationStatus
+     */
+    public ResourceCredentialOperationStatus deletePWDCredential(String clientId, String token) {
+        GetResourceCredentialByTokenRequest tokenRequest = GetResourceCredentialByTokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setToken(token)
+                .build();
+
+        return blockingStub.deletePWDCredential(tokenRequest);
+    }
+
+
+}
diff --git a/custos-client-sdks/custos-java-clients/sharing-management-client/pom.xml b/custos-client-sdks/custos-java-clients/sharing-management-client/pom.xml
new file mode 100644
index 0000000..9b58a1a
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/sharing-management-client/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-java-clients</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sharing-management-client</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>sharing-management-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-clients-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>
+                        ../../../custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/proto
+                    </protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/custos-client-sdks/custos-java-clients/sharing-management-client/src/main/java/org/apache/custos/sharing/management/client/SharingManagementClient.java b/custos-client-sdks/custos-java-clients/sharing-management-client/src/main/java/org/apache/custos/sharing/management/client/SharingManagementClient.java
new file mode 100644
index 0000000..0d81812
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/sharing-management-client/src/main/java/org/apache/custos/sharing/management/client/SharingManagementClient.java
@@ -0,0 +1,273 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.management.client;
+
+import io.grpc.ManagedChannel;
+import io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.NettyChannelBuilder;
+import io.grpc.stub.MetadataUtils;
+import org.apache.custos.clients.core.ClientUtils;
+import org.apache.custos.sharing.management.service.SharingManagementServiceGrpc;
+import org.apache.custos.sharing.service.*;
+
+import java.io.IOException;
+
+/**
+ * Java client to connect with SharingManagementClient
+ */
+public class SharingManagementClient {
+
+    private ManagedChannel managedChannel;
+
+    private SharingManagementServiceGrpc.SharingManagementServiceBlockingStub blockingStub;
+
+
+    public SharingManagementClient(String serviceHost, int servicePort, String clientId,
+                                   String clientSecret) throws IOException {
+        managedChannel = NettyChannelBuilder.forAddress(serviceHost, servicePort)
+                .sslContext(GrpcSslContexts
+                        .forClient()
+                        .trustManager(ClientUtils.getServerCertificate(serviceHost, clientId, clientSecret)) // public key
+                        .build())
+                .build();
+
+        blockingStub = SharingManagementServiceGrpc.newBlockingStub(managedChannel);
+        blockingStub = MetadataUtils.attachHeaders(blockingStub, ClientUtils.getAuthorizationHeader(clientId, clientSecret));
+    }
+
+
+    public Status createEntityType(String clientId, EntityType entityType) {
+
+        EntityTypeRequest entityTypeRequest = EntityTypeRequest
+                .newBuilder()
+                .setEntityType(entityType)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.createEntityType(entityTypeRequest);
+
+    }
+
+
+    public Status updateEntityType(String clientId, EntityType entityType) {
+        EntityTypeRequest entityTypeRequest = EntityTypeRequest
+                .newBuilder()
+                .setEntityType(entityType)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.createEntityType(entityTypeRequest);
+    }
+
+
+    public Status deleteEntityType(String clientId, EntityType entityType) {
+        EntityTypeRequest entityTypeRequest = EntityTypeRequest
+                .newBuilder()
+                .setEntityType(entityType)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.deleteEntityType(entityTypeRequest);
+    }
+
+
+    public EntityType getEntityType(String clientId, EntityType entityType) {
+        EntityTypeRequest entityTypeRequest = EntityTypeRequest
+                .newBuilder()
+                .setEntityType(entityType)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.getEntityType(entityTypeRequest);
+    }
+
+
+    public EntityTypes getEntityTypes(String clientId, SearchRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+
+        return blockingStub.getEntityTypes(request);
+    }
+
+
+    public Status createPermissionType(String clientId, PermissionType permissionType) {
+        PermissionTypeRequest entityTypeRequest = PermissionTypeRequest
+                .newBuilder()
+                .setPermissionType(permissionType)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.createPermissionType(entityTypeRequest);
+    }
+
+
+    public Status updatePermissionType(String clientId, PermissionType permissionType) {
+        PermissionTypeRequest entityTypeRequest = PermissionTypeRequest
+                .newBuilder()
+                .setPermissionType(permissionType)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.updatePermissionType(entityTypeRequest);
+    }
+
+
+    public Status deletePermissionType(String clientId, PermissionType permissionType) {
+        PermissionTypeRequest entityTypeRequest = PermissionTypeRequest
+                .newBuilder()
+                .setPermissionType(permissionType)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.deletePermissionType(entityTypeRequest);
+    }
+
+
+    public PermissionType getPermissionType(String clientId, PermissionType permissionType) {
+        PermissionTypeRequest entityTypeRequest = PermissionTypeRequest
+                .newBuilder()
+                .setPermissionType(permissionType)
+                .setClientId(clientId)
+                .build();
+        return blockingStub.getPermissionType(entityTypeRequest);
+    }
+
+
+    public PermissionTypes getPermissionTypes(String clientId, SearchRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+
+        return blockingStub.getPermissionTypes(request);
+    }
+
+
+    public Status createEntity(String clientId, Entity entity) {
+
+        EntityRequest entityRequest = EntityRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setEntity(entity)
+                .build();
+        return blockingStub.createEntity(entityRequest);
+
+    }
+
+
+    public Status updateEntity(String clientId, Entity entity) {
+        EntityRequest entityRequest = EntityRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setEntity(entity)
+                .build();
+        return blockingStub.updateEntity(entityRequest);
+
+    }
+
+
+    public Status isEntityExists(String clientId, Entity entity) {
+        EntityRequest entityRequest = EntityRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setEntity(entity)
+                .build();
+        return blockingStub.isEntityExists(entityRequest);
+
+    }
+
+
+    public Entity getEntity(String clientId, Entity entity) {
+        EntityRequest entityRequest = EntityRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setEntity(entity)
+                .build();
+        return blockingStub.getEntity(entityRequest);
+
+    }
+
+
+    public Status deleteEntity(String clientId, Entity entity) {
+
+        EntityRequest entityRequest = EntityRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setEntity(entity)
+                .build();
+        return blockingStub.deleteEntity(entityRequest);
+    }
+
+
+    public Entities searchEntities(String clientId, SearchRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.searchEntities(request);
+    }
+
+
+    public SharedOwners getListOfSharedUsers(String clientId, SharingRequest request) {
+
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.getListOfSharedUsers(request);
+
+
+    }
+
+
+    public SharedOwners getListOfDirectlySharedUsers(String clientId, SharingRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.getListOfDirectlySharedUsers(request);
+
+    }
+
+
+    public SharedOwners getListOfSharedGroups(String clientId, SharingRequest request) {
+
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.getListOfSharedGroups(request);
+    }
+
+
+    public SharedOwners getListOfDirectlySharedGroups(String clientId, SharingRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.getListOfDirectlySharedGroups(request);
+    }
+
+
+    public Status shareEntityWithUsers(String clientId, SharingRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.shareEntityWithUsers(request);
+    }
+
+
+    public Status shareEntityWithGroups(String clientId, SharingRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.shareEntityWithGroups(request);
+    }
+
+
+    public Status revokeEntitySharingFromUsers(String clientId, SharingRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.revokeEntitySharingFromUsers(request);
+    }
+
+
+    public Status revokeEntitySharingFromGroups(String clientId, SharingRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.revokeEntitySharingFromGroups(request);
+    }
+
+
+    public Status userHasAccess(String clientId, SharingRequest request) {
+        request = request.toBuilder().setClientId(clientId).build();
+        return blockingStub.userHasAccess(request);
+    }
+
+
+}
diff --git a/custos-client-sdks/custos-java-clients/tenant-management-client/pom.xml b/custos-client-sdks/custos-java-clients/tenant-management-client/pom.xml
new file mode 100644
index 0000000..d499c8c
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/tenant-management-client/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-java-clients</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>tenant-management-client</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-management-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-clients-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>
+                        ../../../custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/proto
+                    </protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-java-clients/tenant-management-client/src/main/java/org/apache/custos/tenant/manamgement/client/SuperAdminOperationsClient.java b/custos-client-sdks/custos-java-clients/tenant-management-client/src/main/java/org/apache/custos/tenant/manamgement/client/SuperAdminOperationsClient.java
new file mode 100644
index 0000000..6b217ac
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/tenant-management-client/src/main/java/org/apache/custos/tenant/manamgement/client/SuperAdminOperationsClient.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.manamgement.client;
+
+import io.grpc.ManagedChannel;
+import io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.NettyChannelBuilder;
+import io.grpc.stub.MetadataUtils;
+import org.apache.custos.clients.core.ClientUtils;
+import org.apache.custos.tenant.management.service.CreateTenantResponse;
+import org.apache.custos.tenant.management.service.TenantManagementServiceGrpc;
+import org.apache.custos.tenant.profile.service.*;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * The class containes operations permitted only by super admin tenant
+ */
+public class SuperAdminOperationsClient {
+
+    private ManagedChannel managedChannel;
+
+    private TenantManagementServiceGrpc.TenantManagementServiceBlockingStub blockingStubWithoutHeader;
+    private TenantManagementServiceGrpc.TenantManagementServiceBlockingStub blockingStub;
+    private TenantManagementServiceGrpc.TenantManagementServiceBlockingStub unAuthorizedStub;
+
+    public SuperAdminOperationsClient(String serviceHost, int servicePort, String clientId,
+                                      String clientSecret) throws IOException {
+
+        managedChannel = NettyChannelBuilder.forAddress(serviceHost, servicePort)
+                .sslContext(GrpcSslContexts
+                        .forClient()
+                        .trustManager(ClientUtils.getServerCertificate(serviceHost, clientId, clientSecret)) // public key
+                        .build())
+                .build();
+
+        blockingStubWithoutHeader = TenantManagementServiceGrpc.newBlockingStub(managedChannel);
+        blockingStub = TenantManagementServiceGrpc.newBlockingStub(managedChannel);
+
+        blockingStub = MetadataUtils.attachHeaders(blockingStub,
+                ClientUtils.getAuthorizationHeader(clientId, clientSecret));
+    }
+
+
+    /**
+     * Register admin tenant
+     *
+     * @param client_name
+     * @param requester_email
+     * @param admin_frist_name
+     * @param admin_last_name
+     * @param admin_email
+     * @param admin_username
+     * @param admin_password
+     * @param contacts
+     * @param redirect_uris
+     * @param client_uri
+     * @param scope
+     * @param domain
+     * @param logo_uri
+     * @param comment
+     * @return
+     */
+    public CreateTenantResponse registerAdminTenant(String client_name, String requester_email, String admin_frist_name,
+                                                    String admin_last_name, String admin_email, String admin_username,
+                                                    String admin_password, String[] contacts, String[] redirect_uris,
+                                                    String client_uri, String scope, String domain, String logo_uri,
+                                                    String comment) {
+        Tenant tenant = Tenant.newBuilder()
+                .setClientName(client_name)
+                .setRequesterEmail(requester_email)
+                .setAdminFirstName(admin_frist_name)
+                .setAdminLastName(admin_last_name)
+                .setAdminEmail(admin_email)
+                .setAdminUsername(admin_username)
+                .setAdminPassword(admin_password)
+                .addAllContacts(Arrays.asList(contacts))
+                .addAllRedirectUris(Arrays.asList(redirect_uris))
+                .setClientUri(client_uri)
+                .setScope(scope)
+                .setDomain(domain)
+                .setLogoUri(logo_uri)
+                .setComment(comment)
+                .setApplicationType("web")
+                .build();
+
+        return blockingStubWithoutHeader.createTenant(tenant);
+
+    }
+
+
+    /**
+     * Get all tenants mapping to given status and requested by user
+     *
+     * @param offset
+     * @param limit
+     * @param status
+     * @param requesterEmail
+     * @return
+     */
+    public GetAllTenantsResponse getAllTenants(int offset, int limit, String status, String requesterEmail) {
+
+        GetTenantsRequest request = GetTenantsRequest
+                .newBuilder()
+                .setStatus(TenantStatus.valueOf(status))
+                .setLimit(limit)
+                .setOffset(offset)
+                .setRequesterEmail(requesterEmail)
+                .build();
+        return blockingStub.getAllTenants(request);
+
+    }
+
+
+    /**
+     * Update tenant status
+     *
+     * @param adminUserToken
+     * @param clientId
+     * @param status
+     * @return
+     */
+    public UpdateStatusResponse updateTenantStatus(String adminUserToken, String clientId, String status) {
+
+        UpdateStatusRequest request = UpdateStatusRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setStatus(TenantStatus.valueOf(status))
+                .build();
+
+        TenantManagementServiceGrpc.TenantManagementServiceBlockingStub blockingStub =
+                MetadataUtils.attachHeaders(this.blockingStub, ClientUtils.getAuthorizationHeader(adminUserToken));
+        return blockingStub.updateTenantStatus(request);
+
+
+    }
+
+
+}
diff --git a/custos-client-sdks/custos-java-clients/tenant-management-client/src/main/java/org/apache/custos/tenant/manamgement/client/TenantManagementClient.java b/custos-client-sdks/custos-java-clients/tenant-management-client/src/main/java/org/apache/custos/tenant/manamgement/client/TenantManagementClient.java
new file mode 100644
index 0000000..613a87d
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/tenant-management-client/src/main/java/org/apache/custos/tenant/manamgement/client/TenantManagementClient.java
@@ -0,0 +1,255 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.manamgement.client;
+
+import io.grpc.ManagedChannel;
+import io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.NettyChannelBuilder;
+import io.grpc.stub.MetadataUtils;
+import org.apache.custos.clients.core.ClientUtils;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.tenant.management.service.DeleteTenantRequest;
+import org.apache.custos.tenant.management.service.GetTenantRequest;
+import org.apache.custos.tenant.management.service.GetTenantResponse;
+import org.apache.custos.tenant.management.service.*;
+import org.apache.custos.tenant.profile.service.*;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * This class contains tenant management operations
+ */
+public class TenantManagementClient {
+
+    private ManagedChannel managedChannel;
+
+    private TenantManagementServiceGrpc.TenantManagementServiceBlockingStub blockingStub;
+
+
+    public TenantManagementClient(String serviceHost, int servicePort, String clientId,
+                                  String clientSecret) throws IOException {
+
+        managedChannel = NettyChannelBuilder.forAddress(serviceHost, servicePort)
+                .sslContext(GrpcSslContexts
+                        .forClient()
+                        .trustManager(ClientUtils.getServerCertificate(serviceHost, clientId, clientSecret)) // public key
+                        .build())
+                .build();
+
+        blockingStub = TenantManagementServiceGrpc.newBlockingStub(managedChannel);
+
+        blockingStub = MetadataUtils.attachHeaders(blockingStub,
+                ClientUtils.getAuthorizationHeader(clientId, clientSecret));
+
+    }
+
+
+    /**
+     * Register child tenant
+     * @param client_name
+     * @param requester_email
+     * @param admin_frist_name
+     * @param admin_last_name
+     * @param admin_email
+     * @param admin_username
+     * @param admin_password
+     * @param contacts
+     * @param redirect_uris
+     * @param client_uri
+     * @param scope
+     * @param domain
+     * @param logo_uri
+     * @param comment
+     * @return
+     */
+    public CreateTenantResponse registerTenant(String client_name, String requester_email, String admin_frist_name,
+                                               String admin_last_name, String admin_email, String admin_username,
+                                               String admin_password, String[] contacts, String[] redirect_uris,
+                                               String client_uri, String scope, String domain, String logo_uri,
+                                               String comment) {
+        Tenant tenant = Tenant.newBuilder()
+                .setClientName(client_name)
+                .setRequesterEmail(requester_email)
+                .setAdminFirstName(admin_frist_name)
+                .setAdminLastName(admin_last_name)
+                .setAdminEmail(admin_email)
+                .setAdminUsername(admin_username)
+                .setAdminPassword(admin_password)
+                .addAllContacts(Arrays.asList(contacts))
+                .addAllRedirectUris(Arrays.asList(redirect_uris))
+                .setClientUri(client_uri)
+                .setScope(scope)
+                .setDomain(domain)
+                .setLogoUri(logo_uri)
+                .setComment(comment)
+                .setApplicationType("web")
+                .build();
+
+        return blockingStub.createTenant(tenant);
+
+    }
+
+
+    /**
+     * Update tenant
+     * @param clientId
+     * @param client_name
+     * @param requester_email
+     * @param admin_frist_name
+     * @param admin_last_name
+     * @param admin_email
+     * @param admin_username
+     * @param admin_password
+     * @param contacts
+     * @param redirect_uris
+     * @param client_uri
+     * @param scope
+     * @param domain
+     * @param logo_uri
+     * @param comment
+     * @return
+     */
+    public GetTenantResponse updateTenant(String clientId, String client_name, String requester_email, String admin_frist_name,
+                                          String admin_last_name, String admin_email, String admin_username,
+                                          String admin_password, String[] contacts, String[] redirect_uris,
+                                          String client_uri, String scope, String domain, String logo_uri,
+                                          String comment) {
+        Tenant tenant = Tenant.newBuilder()
+                .setClientName(client_name)
+                .setRequesterEmail(requester_email)
+                .setAdminFirstName(admin_frist_name)
+                .setAdminLastName(admin_last_name)
+                .setAdminEmail(admin_email)
+                .setAdminUsername(admin_username)
+                .setAdminPassword(admin_password)
+                .addAllContacts(Arrays.asList(contacts))
+                .addAllRedirectUris(Arrays.asList(redirect_uris))
+                .setClientUri(client_uri)
+                .setScope(scope)
+                .setDomain(domain)
+                .setLogoUri(logo_uri)
+                .setComment(comment)
+                .setApplicationType("web")
+                .build();
+
+        UpdateTenantRequest updateTenantRequest = UpdateTenantRequest.newBuilder()
+                .setBody(tenant)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.updateTenant(updateTenantRequest);
+
+    }
+
+
+    public GetTenantResponse getTenant(String clientId) {
+        GetTenantRequest tenantRequest = GetTenantRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .build();
+        return blockingStub.getTenant(tenantRequest);
+    }
+
+
+    /**
+     * delete tenant identified by clientId
+     * @param clientId
+     */
+    public void deleteTenant(String clientId) {
+        DeleteTenantRequest tenantRequest = DeleteTenantRequest.newBuilder().setClientId(clientId).build();
+        blockingStub.deleteTenant(tenantRequest);
+    }
+
+
+    /**
+     * Add tenant roles to tenant
+     * @param roleRepresentations
+     * @param clientLevel
+     * @return
+     */
+    public AllRoles addTenantRoles(RoleRepresentation[] roleRepresentations, boolean clientLevel) {
+
+        AddRolesRequest rolesRequest = AddRolesRequest
+                .newBuilder()
+                .addAllRoles(Arrays.asList(roleRepresentations))
+                .setClientLevel(clientLevel)
+                .build();
+        return blockingStub.addTenantRoles(rolesRequest);
+
+    }
+
+    public OperationStatus addProtocolMapper(String name, String attributeName, String claimName, String claimType, String mapperType,
+                                             boolean addToIdToken, boolean addToAccessToken, boolean addToUserInfo, boolean multiValued,
+                                             boolean aggregreteMultiValues) {
+
+        AddProtocolMapperRequest mapperRequest = AddProtocolMapperRequest.newBuilder()
+                .setName(name)
+                .setAttributeName(attributeName)
+                .setClaimName(claimName)
+                .setMapperType(MapperTypes.valueOf(mapperType))
+                .setClaimType(ClaimJSONTypes.valueOf(claimType))
+                .setAddToAccessToken(addToAccessToken)
+                .setAddToIdToken(addToIdToken)
+                .setAddToUserInfo(addToUserInfo)
+                .setMultiValued(multiValued)
+                .setAggregateAttributeValues(aggregreteMultiValues)
+                .build();
+        return blockingStub.addProtocolMapper(mapperRequest);
+    }
+
+
+    /**
+     * Get child tenants
+     * @param limit
+     * @param offset
+     * @param status
+     * @return
+     */
+    public GetAllTenantsResponse getChildTenants(int limit, int offset, String status) {
+
+        GetTenantsRequest request = GetTenantsRequest
+                .newBuilder()
+                .setLimit(limit)
+                .setOffset(offset)
+                .setStatus(TenantStatus.valueOf(status))
+                .build();
+
+        return blockingStub.getChildTenants(request);
+    }
+
+
+    /**
+     * provides all tenants requested by given email
+     * @param email
+     * @return
+     */
+    public GetAllTenantsForUserResponse getAllTenants(String email) {
+
+        GetAllTenantsForUserRequest request = GetAllTenantsForUserRequest
+                .newBuilder()
+                .setRequesterEmail(email)
+                .build();
+
+        return blockingStub.getAllTenantsForUser(request);
+    }
+
+
+}
diff --git a/custos-client-sdks/custos-java-clients/user-management-client/pom.xml b/custos-client-sdks/custos-java-clients/user-management-client/pom.xml
new file mode 100644
index 0000000..fb87deb
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/user-management-client/pom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-java-clients</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>user-management-client</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-management-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-clients-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>
+                        ../../../custos-integration-services/user-management-service-parent/user-management-service/src/main/proto
+                    </protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-java-clients/user-management-client/src/main/java/org/apache/custos/user/management/client/UserManagementClient.java b/custos-client-sdks/custos-java-clients/user-management-client/src/main/java/org/apache/custos/user/management/client/UserManagementClient.java
new file mode 100644
index 0000000..8394b69
--- /dev/null
+++ b/custos-client-sdks/custos-java-clients/user-management-client/src/main/java/org/apache/custos/user/management/client/UserManagementClient.java
@@ -0,0 +1,565 @@
+package org.apache.custos.user.management.client;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+import io.grpc.ManagedChannel;
+import io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.NettyChannelBuilder;
+import io.grpc.stub.MetadataUtils;
+import org.apache.custos.clients.core.ClientUtils;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.user.management.service.UserManagementServiceGrpc;
+import org.apache.custos.user.management.service.UserProfileRequest;
+import org.apache.custos.user.profile.service.GetAllUserProfilesResponse;
+import org.apache.custos.user.profile.service.UserProfile;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * The class containes operations permitted for user management client
+ */
+public class UserManagementClient {
+
+    private ManagedChannel managedChannel;
+
+    private UserManagementServiceGrpc.UserManagementServiceBlockingStub blockingStub;
+
+    private String clientId ;
+
+    private String clientSec;
+
+
+    public UserManagementClient(String serviceHost, int servicePort, String clientId,
+                                String clientSecret) throws IOException {
+
+        managedChannel = NettyChannelBuilder.forAddress(serviceHost, servicePort)
+                .sslContext(GrpcSslContexts
+                        .forClient()
+                        .trustManager(ClientUtils.getServerCertificate(serviceHost, clientId, clientSecret)) // public key
+                        .build())
+                .build();
+
+        blockingStub = UserManagementServiceGrpc.newBlockingStub(managedChannel);
+
+
+        blockingStub = MetadataUtils.attachHeaders(blockingStub,
+                ClientUtils.getAuthorizationHeader(clientId, clientSecret));
+
+        this.clientId = clientId;
+
+        this.clientSec = clientSecret;
+
+    }
+
+    public RegisterUserResponse registerUser(String username, String firstName, String lastName,
+                                             String password, String email, boolean isTempPassword) {
+
+        UserRepresentation userRepresentation = UserRepresentation
+                .newBuilder()
+                .setUsername(username)
+                .setFirstName(firstName)
+                .setLastName(lastName)
+                .setPassword(password)
+                .setEmail(email)
+                .setTemporaryPassword(isTempPassword)
+                .build();
+
+        RegisterUserRequest registerUserRequest = RegisterUserRequest
+                .newBuilder()
+                .setUser(userRepresentation)
+                .build();
+
+        return blockingStub.registerUser(registerUserRequest);
+
+    }
+
+
+    public UserRepresentation enableUser(String userName) {
+
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(userName)
+                .build();
+
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setUser(metadata).build();
+
+        return blockingStub.enableUser(request);
+    }
+
+    public OperationStatus addUserAttributes(String adminToken, UserAttribute[] attributes, String[] users) {
+
+        UserManagementServiceGrpc.UserManagementServiceBlockingStub unAuthorizedStub =
+                UserManagementServiceGrpc.newBlockingStub(managedChannel);
+        unAuthorizedStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AddUserAttributesRequest request = AddUserAttributesRequest
+                .newBuilder()
+                .addAllAttributes(Arrays.asList(attributes))
+                .addAllUsers(Arrays.asList(users))
+                .build();
+        return unAuthorizedStub.addUserAttributes(request);
+
+    }
+
+    public OperationStatus deleteUserAttributes(String adminToken, UserAttribute[] attributes, String[] users) {
+
+        UserManagementServiceGrpc.UserManagementServiceBlockingStub unAuthorizedStub =
+                UserManagementServiceGrpc.newBlockingStub(managedChannel);
+        unAuthorizedStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+
+        DeleteUserAttributeRequest request = DeleteUserAttributeRequest
+                .newBuilder()
+                .addAllAttributes(Arrays.asList(attributes))
+                .addAllUsers(Arrays.asList(users))
+                .build();
+        return unAuthorizedStub.deleteUserAttributes(request);
+
+    }
+
+
+    public OperationStatus addRolesToUsers(String adminToken, String[] roles, String[] username, boolean isClientLevel) {
+        UserManagementServiceGrpc.UserManagementServiceBlockingStub unAuthorizedStub =
+                UserManagementServiceGrpc.newBlockingStub(managedChannel);
+        unAuthorizedStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        AddUserRolesRequest request = AddUserRolesRequest
+                .newBuilder()
+                .addAllRoles(Arrays.asList(roles))
+                .addAllUsernames(Arrays.asList(username))
+                .setClientLevel(isClientLevel)
+                .build();
+        return unAuthorizedStub.addRolesToUsers(request);
+
+    }
+
+
+    public OperationStatus deleteUserRoles(String adminToken, String[] clientRoles, String[] realmRoles, String username) {
+        UserManagementServiceGrpc.UserManagementServiceBlockingStub unAuthorizedStub =
+                UserManagementServiceGrpc.newBlockingStub(managedChannel);
+        unAuthorizedStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        DeleteUserRolesRequest request = DeleteUserRolesRequest
+                .newBuilder()
+                .addAllClientRoles(Arrays.asList(clientRoles))
+                .addAllRoles(Arrays.asList(realmRoles))
+                .setUsername(username)
+                .build();
+        return unAuthorizedStub.deleteUserRoles(request);
+
+    }
+
+
+    public OperationStatus isUserEnabled(String username) {
+
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(username)
+                .build();
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setUser(metadata)
+                .build();
+
+        return blockingStub.isUserEnabled(request);
+    }
+
+
+    public OperationStatus isUsernameAvailable(String username) {
+
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(username)
+                .build();
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setUser(metadata)
+                .build();
+
+        return blockingStub.isUsernameAvailable(request);
+    }
+
+
+    public UserRepresentation getUser(String username) {
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(username)
+                .build();
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setUser(metadata)
+                .build();
+
+        return blockingStub.getUser(request);
+
+    }
+
+
+    public FindUsersResponse findUser(String username, String firstName, String lastName, String email, int offset, int limit) {
+
+        UserSearchMetadata.Builder builder = UserSearchMetadata
+                .newBuilder();
+
+        if (username != null) {
+            builder = builder.setUsername(username);
+        }
+
+        if (firstName != null) {
+            builder = builder.setFirstName(firstName);
+        }
+
+        if (lastName != null) {
+            builder = builder.setFirstName(lastName);
+        }
+
+        if (email != null) {
+            builder = builder.setFirstName(email);
+        }
+        UserSearchMetadata metadata = builder.build();
+
+        FindUsersRequest request = FindUsersRequest
+                .newBuilder()
+                .setUser(metadata)
+                .setLimit(limit)
+                .setOffset(offset)
+                .build();
+
+        return blockingStub.findUsers(request);
+
+    }
+
+
+    public OperationStatus resetUserPassword(String username, String password) {
+
+        ResetUserPassword userPassword = ResetUserPassword
+                .newBuilder()
+                .setPassword(password)
+                .setUsername(username)
+                .build();
+
+        return blockingStub.resetPassword(userPassword);
+
+    }
+
+
+    public OperationStatus deleteUser(String adminToken, String username) {
+
+        UserManagementServiceGrpc.UserManagementServiceBlockingStub unAuthorizedStub =
+                UserManagementServiceGrpc.newBlockingStub(managedChannel);
+        unAuthorizedStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getAuthorizationHeader(adminToken));
+
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(username)
+                .build();
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setUser(metadata)
+                .build();
+
+        return unAuthorizedStub.deleteUser(request);
+
+    }
+
+
+    public RegisterUserResponse registerUser(String username, String firstName, String lastName,
+                                             String password, String email, boolean isTempPassword,
+                                             String clientId) {
+
+        UserRepresentation userRepresentation = UserRepresentation
+                .newBuilder()
+                .setUsername(username)
+                .setFirstName(firstName)
+                .setLastName(lastName)
+                .setPassword(password)
+                .setEmail(email)
+                .setTemporaryPassword(isTempPassword)
+                .build();
+
+        RegisterUserRequest registerUserRequest = RegisterUserRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setUser(userRepresentation)
+                .build();
+
+        return blockingStub.registerUser(registerUserRequest);
+
+    }
+
+
+    public UserRepresentation enableUser(String userName, String clientId) {
+
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(userName)
+                .build();
+
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setUser(metadata).build();
+
+        return blockingStub.enableUser(request);
+    }
+
+    public OperationStatus addUserAttributes(UserAttribute[] attributes, String[] users, String clientId) {
+
+
+        AddUserAttributesRequest request = AddUserAttributesRequest
+                .newBuilder()
+                .addAllAttributes(Arrays.asList(attributes))
+                .addAllUsers(Arrays.asList(users))
+                .setClientId(clientId)
+                .build();
+        return blockingStub.addUserAttributes(request);
+
+    }
+
+    public OperationStatus deleteUserAttributes(UserAttribute[] attributes, String[] users, String clientId) {
+
+
+        DeleteUserAttributeRequest request = DeleteUserAttributeRequest
+                .newBuilder()
+                .addAllAttributes(Arrays.asList(attributes))
+                .addAllUsers(Arrays.asList(users))
+                .setClientId(clientId)
+                .build();
+        return blockingStub.deleteUserAttributes(request);
+
+    }
+
+
+    public OperationStatus addRolesToUsers(String[] roles, String[] username,
+                                           boolean isClientLevel, String clientId, String adminToken) {
+        UserManagementServiceGrpc.UserManagementServiceBlockingStub unAuthorizedStub =
+                UserManagementServiceGrpc.newBlockingStub(managedChannel);
+        unAuthorizedStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getUserTokenHeader(adminToken));
+        unAuthorizedStub =MetadataUtils.attachHeaders(unAuthorizedStub,
+                ClientUtils.getAuthorizationHeader(this.clientId, this.clientSec));
+
+        AddUserRolesRequest request = AddUserRolesRequest
+                .newBuilder()
+                .addAllRoles(Arrays.asList(roles))
+                .addAllUsernames(Arrays.asList(username))
+                .setClientLevel(isClientLevel)
+                .setClientId(clientId)
+                .build();
+        return unAuthorizedStub.addRolesToUsers(request);
+
+    }
+
+
+    public OperationStatus deleteUserRoles(String[] clientRoles,
+                                           String[] realmRoles, String username, String clientId, String adminToken) {
+        UserManagementServiceGrpc.UserManagementServiceBlockingStub unAuthorizedStub =
+                UserManagementServiceGrpc.newBlockingStub(managedChannel);
+        unAuthorizedStub =
+                MetadataUtils.attachHeaders(unAuthorizedStub, ClientUtils.getUserTokenHeader(adminToken));
+        unAuthorizedStub =MetadataUtils.attachHeaders(unAuthorizedStub,
+                ClientUtils.getAuthorizationHeader(this.clientId, this.clientSec));
+
+        DeleteUserRolesRequest request = DeleteUserRolesRequest
+                .newBuilder()
+                .addAllClientRoles(Arrays.asList(clientRoles))
+                .addAllRoles(Arrays.asList(realmRoles))
+                .setUsername(username)
+                .setClientId(clientId)
+                .build();
+        return unAuthorizedStub.deleteUserRoles(request);
+
+    }
+
+
+    public OperationStatus isUserEnabled(String username, String clientId) {
+
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(username)
+                .build();
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setUser(metadata)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.isUserEnabled(request);
+    }
+
+
+    public OperationStatus isUsernameAvailable(String username, String clientId) {
+
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(username)
+                .build();
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setUser(metadata)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.isUsernameAvailable(request);
+    }
+
+
+    public UserRepresentation getUser(String username, String clientId) {
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(username)
+                .build();
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setUser(metadata)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.getUser(request);
+
+    }
+
+
+    public GetAllUserProfilesResponse getAllUserProfiles(String clientId) {
+        UserProfileRequest request = UserProfileRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.getAllUserProfilesInTenant(request);
+
+    }
+
+
+    public FindUsersResponse findUsers(String searchString, String username, String firstName,
+                                       String lastName, String email, int offset, int limit, String clientId) {
+
+        UserSearchMetadata.Builder builder = UserSearchMetadata
+                .newBuilder();
+
+        if (username != null) {
+            builder = builder.setUsername(username);
+        }
+
+        if (firstName != null) {
+            builder = builder.setFirstName(firstName);
+        }
+
+        if (lastName != null) {
+            builder = builder.setFirstName(lastName);
+        }
+
+        if (email != null) {
+            builder = builder.setFirstName(email);
+        }
+
+        if (searchString != null) {
+            builder = builder.setId(searchString);
+        }
+        UserSearchMetadata metadata = builder.build();
+
+        FindUsersRequest request = FindUsersRequest
+                .newBuilder()
+                .setUser(metadata)
+                .setLimit(limit)
+                .setOffset(offset)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.findUsers(request);
+
+    }
+
+
+    public OperationStatus resetUserPassword(String username, String password, String clientId) {
+
+        ResetUserPassword userPassword = ResetUserPassword
+                .newBuilder()
+                .setPassword(password)
+                .setUsername(username)
+                .setClientId(clientId)
+                .build();
+
+        return blockingStub.resetPassword(userPassword);
+
+    }
+
+
+    public OperationStatus deleteUser(String username, String clientId, String adminToken) {
+
+        UserManagementServiceGrpc.UserManagementServiceBlockingStub stub =
+                UserManagementServiceGrpc.newBlockingStub(managedChannel);
+                stub = MetadataUtils.attachHeaders(stub,
+                        ClientUtils.getAuthorizationHeader(this.clientId, this.clientSec));
+                MetadataUtils.attachHeaders(stub, ClientUtils.getUserTokenHeader(adminToken));
+
+        UserSearchMetadata metadata = UserSearchMetadata
+                .newBuilder()
+                .setUsername(username)
+                .build();
+
+        UserSearchRequest request = UserSearchRequest
+                .newBuilder()
+                .setUser(metadata)
+                .setClientId(clientId)
+                .build();
+
+        return stub.deleteUser(request);
+
+    }
+
+
+    public UserProfile updateUserProfile(String username, String firstName, String lastName, String email,
+                                         String clientId) {
+
+
+        UserProfile userProfile = UserProfile.newBuilder()
+                .setUsername(username)
+                .setFirstName(firstName)
+                .setLastName(lastName)
+                .setEmail(email)
+                .build();
+
+        UserProfileRequest userProfileRequest = UserProfileRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setUserProfile(userProfile)
+                .build();
+
+        return blockingStub.updateUserProfile(userProfileRequest);
+
+    }
+
+}
diff --git a/custos-client-sdks/custos-java-sdk/pom.xml b/custos-client-sdks/custos-java-sdk/pom.xml
new file mode 100644
index 0000000..a9dfc39
--- /dev/null
+++ b/custos-client-sdks/custos-java-sdk/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-client-sdks</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-java-sdk</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>agent-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>group-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>resource-secret-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>sharing-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptorRefs>
+                                <descriptorRef>jar-with-dependencies</descriptorRef>
+                            </descriptorRefs>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
+                            <overWriteReleases>false</overWriteReleases>
+                            <overWriteSnapshots>false</overWriteSnapshots>
+                            <overWriteIfNewer>true</overWriteIfNewer>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+
+
+    </build>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-java-sdk/src/main/java/org/apache/custos/clients/CustosClientProvider.java b/custos-client-sdks/custos-java-sdk/src/main/java/org/apache/custos/clients/CustosClientProvider.java
new file mode 100644
index 0000000..fa3f05a
--- /dev/null
+++ b/custos-client-sdks/custos-java-sdk/src/main/java/org/apache/custos/clients/CustosClientProvider.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.clients;
+
+import org.apache.custos.agent.management.client.AgentManagementClient;
+import org.apache.custos.group.management.client.GroupManagementClient;
+import org.apache.custos.identity.management.client.IdentityManagementClient;
+import org.apache.custos.resource.secret.management.client.ResourceSecretManagementClient;
+import org.apache.custos.sharing.management.client.SharingManagementClient;
+import org.apache.custos.tenant.manamgement.client.TenantManagementClient;
+import org.apache.custos.user.management.client.UserManagementClient;
+
+import java.io.IOException;
+
+/**
+ * The class responsible for provides the Custos clients
+ */
+public class CustosClientProvider {
+
+
+    private String serverHost;
+
+    private int serverPort;
+
+    private String clientId;
+
+    private String clientSec;
+
+
+    private CustosClientProvider(String serverHost, int serverPort, String clientId, String clientSec) {
+        this.serverHost = serverHost;
+        this.serverPort = serverPort;
+        this.clientId = clientId;
+        this.clientSec = clientSec;
+    }
+
+
+    public IdentityManagementClient getIdentityManagementClient() throws IOException {
+        return new IdentityManagementClient(this.serverHost, this.serverPort, this.clientId, this.clientSec);
+    }
+
+
+    public TenantManagementClient getTenantManagementClient() throws IOException {
+        return new TenantManagementClient(this.serverHost, this.serverPort, this.clientId, this.clientSec);
+    }
+
+    public AgentManagementClient getAgentManagementClient() throws IOException {
+        return new AgentManagementClient(this.serverHost, this.serverPort, this.clientId, this.clientSec);
+    }
+
+    public GroupManagementClient getGroupManagementClient() throws IOException {
+        return new GroupManagementClient(this.serverHost, this.serverPort, this.clientId, this.clientSec);
+    }
+
+    public ResourceSecretManagementClient getResourceSecretManagementClient() throws IOException {
+        return new ResourceSecretManagementClient(this.serverHost, this.serverPort, this.clientId, this.clientSec);
+    }
+
+    public SharingManagementClient getSharingManagementClient() throws IOException {
+        return new SharingManagementClient(this.serverHost, this.serverPort, this.clientId, this.clientSec);
+    }
+
+    public UserManagementClient getUserManagementClient() throws IOException {
+        return new UserManagementClient(this.serverHost, this.serverPort, this.clientId, this.clientSec);
+    }
+
+
+    public static class Builder {
+
+        private String serverHost;
+        private int serverPort;
+        private String clientId;
+
+        private String clientSec;
+
+
+        public Builder() {
+        }
+
+        public Builder setServerHost(String serverHost) {
+            this.serverHost = serverHost;
+            return this;
+        }
+
+        public Builder setServerPort(int serverPort) {
+            this.serverPort = serverPort;
+            return this;
+        }
+
+        public Builder setClientId(String clientId) {
+            this.clientId = clientId;
+            return this;
+        }
+
+        public Builder setClientSec(String clientSec) {
+            this.clientSec = clientSec;
+            return this;
+        }
+
+
+        public CustosClientProvider build() {
+            if (serverHost == null || serverPort == 0 || clientId == null || clientSec == null) {
+                throw new NullPointerException("Server Host, Server Port, clientId, clientSec   should not be null");
+            }
+
+            return new CustosClientProvider(this.serverHost, this.serverPort, this.clientId, this.clientSec);
+
+        }
+
+    }
+
+
+}
diff --git a/custos-client-sdks/custos-js-sdk/clients/ResourceManagementClient.js b/custos-client-sdks/custos-js-sdk/clients/ResourceManagementClient.js
new file mode 100644
index 0000000..1f67fe7
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/clients/ResourceManagementClient.js
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+const {} = require('../stubs/integration-services/resource-secret-management/ResourceSecretManagementService_pb');
+const {ResourceSecretManagementServiceClient} = require('../stubs/integration-services/resource-secret-management/ResourceSecretManagementService_grpc_web_pb');
+const {GetSecretRequest, SecretMetadata, ResourceOwnerType, ResourceType} = require('../stubs/core-services/resource-secret-service/ResourceSecretService_pb');
+
+var resourceSecretService = new ResourceSecretManagementServiceClient("https://custos.scigap.org/grpcweb", null, null);
+
+var request = new GetSecretRequest();
+
+
+var resourceOwnerType = ResourceOwnerType.CUSTOS;
+var resourceType = ResourceType.SERVER_CERTIFICATE;
+
+
+var secretMetadata = new SecretMetadata();
+secretMetadata.setResourceType(resourceType);
+secretMetadata.setOwnerType(resourceOwnerType);
+request.setMetadata(secretMetadata);
+
+
+const header = {'Authorization': 'Bearer XXX'}
+
+resourceSecretService.getSecret(request, header, (err, response) => {
+
+    if (err) {
+        console.log(err)
+    } else {
+        console.log(response)
+    }
+
+})
\ No newline at end of file
diff --git a/custos-client-sdks/custos-js-sdk/clients/test.html b/custos-client-sdks/custos-js-sdk/clients/test.html
new file mode 100644
index 0000000..9abb2bf
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/clients/test.html
@@ -0,0 +1,30 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~  
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~  
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<!DOCTYPE html>
+<html>
+<body>
+
+<h1>The script src attribute</h1>
+
+<script src="../dist/main.js" >
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/custos-client-sdks/custos-js-sdk/package-lock.json b/custos-client-sdks/custos-js-sdk/package-lock.json
new file mode 100644
index 0000000..5ccc329
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/package-lock.json
@@ -0,0 +1,4183 @@
+{
+  "name": "grpc-web-custos-sdk",
+  "requires": true,
+  "lockfileVersion": 1,
+  "dependencies": {
+    "@webassemblyjs/ast": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
+      "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/helper-module-context": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz",
+      "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-api-error": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz",
+      "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-buffer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz",
+      "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-code-frame": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz",
+      "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-fsm": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz",
+      "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-module-context": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz",
+      "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz",
+      "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-section": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz",
+      "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0"
+      }
+    },
+    "@webassemblyjs/ieee754": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz",
+      "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==",
+      "dev": true,
+      "requires": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "@webassemblyjs/leb128": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz",
+      "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==",
+      "dev": true,
+      "requires": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/utf8": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz",
+      "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==",
+      "dev": true
+    },
+    "@webassemblyjs/wasm-edit": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz",
+      "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/helper-wasm-section": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-opt": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0",
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-gen": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz",
+      "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-opt": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz",
+      "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz",
+      "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wast-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz",
+      "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/floating-point-hex-parser": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-code-frame": "1.9.0",
+        "@webassemblyjs/helper-fsm": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/wast-printer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz",
+      "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true
+    },
+    "@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "dev": true
+    },
+    "JSONStream": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+      "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+      "dev": true,
+      "requires": {
+        "jsonparse": "^1.2.0",
+        "through": ">=2.2.7 <3"
+      }
+    },
+    "acorn": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz",
+      "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==",
+      "dev": true
+    },
+    "acorn-node": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+      "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.0.0",
+        "acorn-walk": "^7.0.0",
+        "xtend": "^4.0.2"
+      }
+    },
+    "acorn-walk": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+      "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+      "dev": true
+    },
+    "ajv": {
+      "version": "6.12.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
+      "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
+      "dev": true,
+      "requires": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "ajv-errors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+      "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
+      "dev": true
+    },
+    "ajv-keywords": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.0.tgz",
+      "integrity": "sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw==",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "requires": {
+        "color-convert": "^1.9.0"
+      }
+    },
+    "anymatch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+      "dev": true
+    },
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true
+    },
+    "asn1.js": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+      "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "assert": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+      "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "util": "0.10.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        },
+        "util": {
+          "version": "0.10.3",
+          "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.1"
+          }
+        }
+      }
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "async-each": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+      "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
+      "dev": true,
+      "optional": true
+    },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "base64-js": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+      "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
+      "dev": true
+    },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true
+    },
+    "binary-extensions": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
+      "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
+      "dev": true,
+      "optional": true
+    },
+    "bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+      "dev": true
+    },
+    "bn.js": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
+      "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==",
+      "dev": true
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "^1.1.0",
+        "array-unique": "^0.3.2",
+        "extend-shallow": "^2.0.1",
+        "fill-range": "^4.0.0",
+        "isobject": "^3.0.1",
+        "repeat-element": "^1.1.2",
+        "snapdragon": "^0.8.1",
+        "snapdragon-node": "^2.0.1",
+        "split-string": "^3.0.2",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browser-pack": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz",
+      "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "combine-source-map": "~0.8.0",
+        "defined": "^1.0.0",
+        "safe-buffer": "^5.1.1",
+        "through2": "^2.0.0",
+        "umd": "^3.0.0"
+      }
+    },
+    "browser-resolve": {
+      "version": "1.11.3",
+      "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
+      "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
+      "dev": true,
+      "requires": {
+        "resolve": "1.1.7"
+      },
+      "dependencies": {
+        "resolve": {
+          "version": "1.1.7",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+          "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+          "dev": true
+        }
+      }
+    },
+    "browserify": {
+      "version": "16.5.1",
+      "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.1.tgz",
+      "integrity": "sha512-EQX0h59Pp+0GtSRb5rL6OTfrttlzv+uyaUVlK6GX3w11SQ0jKPKyjC/54RhPR2ib2KmfcELM06e8FxcI5XNU2A==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "assert": "^1.4.0",
+        "browser-pack": "^6.0.1",
+        "browser-resolve": "^1.11.0",
+        "browserify-zlib": "~0.2.0",
+        "buffer": "~5.2.1",
+        "cached-path-relative": "^1.0.0",
+        "concat-stream": "^1.6.0",
+        "console-browserify": "^1.1.0",
+        "constants-browserify": "~1.0.0",
+        "crypto-browserify": "^3.0.0",
+        "defined": "^1.0.0",
+        "deps-sort": "^2.0.0",
+        "domain-browser": "^1.2.0",
+        "duplexer2": "~0.1.2",
+        "events": "^2.0.0",
+        "glob": "^7.1.0",
+        "has": "^1.0.0",
+        "htmlescape": "^1.1.0",
+        "https-browserify": "^1.0.0",
+        "inherits": "~2.0.1",
+        "insert-module-globals": "^7.0.0",
+        "labeled-stream-splicer": "^2.0.0",
+        "mkdirp-classic": "^0.5.2",
+        "module-deps": "^6.0.0",
+        "os-browserify": "~0.3.0",
+        "parents": "^1.0.1",
+        "path-browserify": "~0.0.0",
+        "process": "~0.11.0",
+        "punycode": "^1.3.2",
+        "querystring-es3": "~0.2.0",
+        "read-only-stream": "^2.0.0",
+        "readable-stream": "^2.0.2",
+        "resolve": "^1.1.4",
+        "shasum": "^1.0.0",
+        "shell-quote": "^1.6.1",
+        "stream-browserify": "^2.0.0",
+        "stream-http": "^3.0.0",
+        "string_decoder": "^1.1.1",
+        "subarg": "^1.0.0",
+        "syntax-error": "^1.1.1",
+        "through2": "^2.0.0",
+        "timers-browserify": "^1.0.1",
+        "tty-browserify": "0.0.1",
+        "url": "~0.11.0",
+        "util": "~0.10.1",
+        "vm-browserify": "^1.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "randombytes": "^2.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "browserify-sign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz",
+      "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.2",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "requires": {
+        "pako": "~1.0.5"
+      }
+    },
+    "buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+      "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+      "dev": true,
+      "requires": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4"
+      }
+    },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "cacache": {
+      "version": "12.0.4",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz",
+      "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.5",
+        "chownr": "^1.1.1",
+        "figgy-pudding": "^3.5.1",
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.1.15",
+        "infer-owner": "^1.0.3",
+        "lru-cache": "^5.1.1",
+        "mississippi": "^3.0.0",
+        "mkdirp": "^0.5.1",
+        "move-concurrently": "^1.0.1",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^2.6.3",
+        "ssri": "^6.0.1",
+        "unique-filename": "^1.1.1",
+        "y18n": "^4.0.0"
+      }
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      }
+    },
+    "cached-path-relative": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz",
+      "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "dev": true
+    },
+    "chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "dependencies": {
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "chokidar": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+      "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "anymatch": "~3.1.1",
+        "braces": "~3.0.2",
+        "fsevents": "~2.1.2",
+        "glob-parent": "~5.1.0",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.4.0"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true,
+          "optional": true
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
+    "chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "dev": true
+    },
+    "chrome-trace-event": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+      "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "cliui": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+      "dev": true,
+      "requires": {
+        "string-width": "^3.1.0",
+        "strip-ansi": "^5.2.0",
+        "wrap-ansi": "^5.1.0"
+      }
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "combine-source-map": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
+      "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=",
+      "dev": true,
+      "requires": {
+        "convert-source-map": "~1.1.0",
+        "inline-source-map": "~0.6.0",
+        "lodash.memoize": "~3.0.3",
+        "source-map": "~0.5.3"
+      }
+    },
+    "commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+      "dev": true
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+      "dev": true
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "console-browserify": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+      "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+      "dev": true
+    },
+    "constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+      "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
+      "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=",
+      "dev": true
+    },
+    "copy-concurrently": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+      "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "fs-write-stream-atomic": "^1.0.8",
+        "iferr": "^0.1.5",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.0"
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "create-ecdh": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+      "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "create-hash": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "cross-spawn": {
+      "version": "6.0.5",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "dev": true,
+      "requires": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      }
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      }
+    },
+    "cyclist": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
+      "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
+      "dev": true
+    },
+    "dash-ast": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz",
+      "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==",
+      "dev": true
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "defined": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+      "dev": true
+    },
+    "deps-sort": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz",
+      "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "shasum-object": "^1.0.0",
+        "subarg": "^1.0.0",
+        "through2": "^2.0.0"
+      }
+    },
+    "des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "detect-file": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+      "dev": true
+    },
+    "detective": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz",
+      "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==",
+      "dev": true,
+      "requires": {
+        "acorn-node": "^1.6.1",
+        "defined": "^1.0.0",
+        "minimist": "^1.1.1"
+      }
+    },
+    "diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "domain-browser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+      "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+      "dev": true
+    },
+    "duplexer2": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+      "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "duplexify": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+      "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "elliptic": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "emoji-regex": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+      "dev": true
+    },
+    "emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "dev": true,
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz",
+      "integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "memory-fs": "^0.5.0",
+        "tapable": "^1.0.0"
+      },
+      "dependencies": {
+        "memory-fs": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+          "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+          "dev": true,
+          "requires": {
+            "errno": "^0.1.3",
+            "readable-stream": "^2.0.1"
+          }
+        }
+      }
+    },
+    "errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "requires": {
+        "prr": "~1.0.1"
+      }
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "eslint-scope": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+      "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.1.0",
+        "estraverse": "^4.1.1"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.1.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true
+    },
+    "events": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
+      "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==",
+      "dev": true
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "requires": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "expand-tilde": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "^1.0.1"
+      }
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "requires": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
+    },
+    "fast-safe-stringify": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
+      "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==",
+      "dev": true
+    },
+    "figgy-pudding": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
+      "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
+      "dev": true
+    },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true,
+      "optional": true
+    },
+    "fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "find-cache-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+      "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+      "dev": true,
+      "requires": {
+        "commondir": "^1.0.1",
+        "make-dir": "^2.0.0",
+        "pkg-dir": "^3.0.0"
+      }
+    },
+    "find-up": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "dev": true,
+      "requires": {
+        "locate-path": "^3.0.0"
+      }
+    },
+    "findup-sync": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
+      "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
+      "dev": true,
+      "requires": {
+        "detect-file": "^1.0.0",
+        "is-glob": "^4.0.0",
+        "micromatch": "^3.0.4",
+        "resolve-dir": "^1.0.1"
+      }
+    },
+    "flush-write-stream": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+      "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.3.6"
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "^0.2.2"
+      }
+    },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
+    "fs-write-stream-atomic": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+      "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "iferr": "^0.1.5",
+        "imurmurhash": "^0.1.4",
+        "readable-stream": "1 || 2"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+      "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+      "dev": true,
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "get-assigned-identifiers": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
+      "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==",
+      "dev": true
+    },
+    "get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "glob-parent": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
+    "global-modules": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+      "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+      "dev": true,
+      "requires": {
+        "global-prefix": "^3.0.0"
+      },
+      "dependencies": {
+        "global-prefix": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+          "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+          "dev": true,
+          "requires": {
+            "ini": "^1.3.5",
+            "kind-of": "^6.0.2",
+            "which": "^1.3.1"
+          }
+        }
+      }
+    },
+    "global-prefix": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "^2.0.2",
+        "homedir-polyfill": "^1.0.1",
+        "ini": "^1.3.4",
+        "is-windows": "^1.0.1",
+        "which": "^1.2.14"
+      }
+    },
+    "google-protobuf": {
+      "version": "3.12.2",
+      "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.12.2.tgz",
+      "integrity": "sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA=="
+    },
+    "graceful-fs": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+      "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+      "dev": true
+    },
+    "grpc-web": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/grpc-web/-/grpc-web-1.2.0.tgz",
+      "integrity": "sha512-QS0RF+xiWnMEiHWyA0A0I8JYYJLOiF/DGEpRQ7vJDOzEZYfmNqI7d7d29sYBbNfTi+arVh2JpeGIX7ch24a+tA=="
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "hash-base": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+      "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "homedir-polyfill": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+      "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+      "dev": true,
+      "requires": {
+        "parse-passwd": "^1.0.0"
+      }
+    },
+    "htmlescape": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
+      "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=",
+      "dev": true
+    },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
+    "ieee754": {
+      "version": "1.1.13",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
+      "dev": true
+    },
+    "iferr": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+      "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+      "dev": true
+    },
+    "import-local": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
+      "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
+      "dev": true,
+      "requires": {
+        "pkg-dir": "^3.0.0",
+        "resolve-cwd": "^2.0.0"
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "infer-owner": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+      "dev": true
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
+    "ini": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true
+    },
+    "inline-source-map": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz",
+      "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=",
+      "dev": true,
+      "requires": {
+        "source-map": "~0.5.3"
+      }
+    },
+    "insert-module-globals": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz",
+      "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "acorn-node": "^1.5.2",
+        "combine-source-map": "^0.8.0",
+        "concat-stream": "^1.6.1",
+        "is-buffer": "^1.1.0",
+        "path-is-absolute": "^1.0.1",
+        "process": "~0.11.0",
+        "through2": "^2.0.0",
+        "undeclared-identifiers": "^1.1.2",
+        "xtend": "^4.0.0"
+      }
+    },
+    "interpret": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+      "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+      "dev": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+      "dev": true
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "is-wsl": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+      "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+      "dev": true
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true
+    },
+    "json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "json-stable-stringify": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz",
+      "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=",
+      "dev": true,
+      "requires": {
+        "jsonify": "~0.0.0"
+      }
+    },
+    "json5": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+      "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.0"
+      }
+    },
+    "jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+      "dev": true
+    },
+    "jsonparse": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+      "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+      "dev": true
+    },
+    "kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "dev": true
+    },
+    "labeled-stream-splicer": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz",
+      "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "stream-splicer": "^2.0.0"
+      }
+    },
+    "loader-runner": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
+      "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==",
+      "dev": true
+    },
+    "loader-utils": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+      "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+      "dev": true,
+      "requires": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^1.0.1"
+      }
+    },
+    "locate-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+      "dev": true,
+      "requires": {
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      }
+    },
+    "lodash.memoize": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
+      "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=",
+      "dev": true
+    },
+    "lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "requires": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "dev": true,
+      "requires": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "^1.0.0"
+      }
+    },
+    "md5.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "memory-fs": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+      "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+      "dev": true,
+      "requires": {
+        "errno": "^0.1.3",
+        "readable-stream": "^2.0.1"
+      }
+    },
+    "micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "braces": "^2.3.1",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "extglob": "^2.0.4",
+        "fragment-cache": "^0.2.1",
+        "kind-of": "^6.0.2",
+        "nanomatch": "^1.2.9",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.2"
+      }
+    },
+    "miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "dev": true
+    },
+    "mississippi": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+      "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
+      "dev": true,
+      "requires": {
+        "concat-stream": "^1.5.0",
+        "duplexify": "^3.4.2",
+        "end-of-stream": "^1.1.0",
+        "flush-write-stream": "^1.0.0",
+        "from2": "^2.1.0",
+        "parallel-transform": "^1.1.0",
+        "pump": "^3.0.0",
+        "pumpify": "^1.3.3",
+        "stream-each": "^1.1.0",
+        "through2": "^2.0.0"
+      }
+    },
+    "mixin-deep": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+      "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "mkdirp-classic": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+      "dev": true
+    },
+    "module-deps": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.2.tgz",
+      "integrity": "sha512-a9y6yDv5u5I4A+IPHTnqFxcaKr4p50/zxTjcQJaX2ws9tN/W6J6YXnEKhqRyPhl494dkcxx951onSKVezmI+3w==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "browser-resolve": "^1.7.0",
+        "cached-path-relative": "^1.0.2",
+        "concat-stream": "~1.6.0",
+        "defined": "^1.0.0",
+        "detective": "^5.2.0",
+        "duplexer2": "^0.1.2",
+        "inherits": "^2.0.1",
+        "parents": "^1.0.0",
+        "readable-stream": "^2.0.2",
+        "resolve": "^1.4.0",
+        "stream-combiner2": "^1.1.1",
+        "subarg": "^1.0.0",
+        "through2": "^2.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "move-concurrently": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+      "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "copy-concurrently": "^1.0.0",
+        "fs-write-stream-atomic": "^1.0.8",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.3"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "nan": {
+      "version": "2.14.1",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
+      "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
+      "dev": true,
+      "optional": true
+    },
+    "nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      }
+    },
+    "neo-async": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
+      "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
+      "dev": true
+    },
+    "nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "dev": true
+    },
+    "node-libs-browser": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
+      "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
+      "dev": true,
+      "requires": {
+        "assert": "^1.1.1",
+        "browserify-zlib": "^0.2.0",
+        "buffer": "^4.3.0",
+        "console-browserify": "^1.1.0",
+        "constants-browserify": "^1.0.0",
+        "crypto-browserify": "^3.11.0",
+        "domain-browser": "^1.1.1",
+        "events": "^3.0.0",
+        "https-browserify": "^1.0.0",
+        "os-browserify": "^0.3.0",
+        "path-browserify": "0.0.1",
+        "process": "^0.11.10",
+        "punycode": "^1.2.4",
+        "querystring-es3": "^0.2.0",
+        "readable-stream": "^2.3.3",
+        "stream-browserify": "^2.0.1",
+        "stream-http": "^2.7.2",
+        "string_decoder": "^1.0.0",
+        "timers-browserify": "^2.0.4",
+        "tty-browserify": "0.0.0",
+        "url": "^0.11.0",
+        "util": "^0.11.0",
+        "vm-browserify": "^1.0.1"
+      },
+      "dependencies": {
+        "buffer": {
+          "version": "4.9.2",
+          "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+          "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+          "dev": true,
+          "requires": {
+            "base64-js": "^1.0.2",
+            "ieee754": "^1.1.4",
+            "isarray": "^1.0.0"
+          }
+        },
+        "events": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
+          "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==",
+          "dev": true
+        },
+        "stream-http": {
+          "version": "2.8.3",
+          "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+          "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+          "dev": true,
+          "requires": {
+            "builtin-status-codes": "^3.0.0",
+            "inherits": "^2.0.1",
+            "readable-stream": "^2.3.6",
+            "to-arraybuffer": "^1.0.0",
+            "xtend": "^4.0.0"
+          }
+        },
+        "timers-browserify": {
+          "version": "2.0.11",
+          "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
+          "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==",
+          "dev": true,
+          "requires": {
+            "setimmediate": "^1.0.4"
+          }
+        },
+        "tty-browserify": {
+          "version": "0.0.0",
+          "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+          "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+          "dev": true
+        },
+        "util": {
+          "version": "0.11.1",
+          "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
+          "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.3"
+          },
+          "dependencies": {
+            "inherits": {
+              "version": "2.0.3",
+              "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+              "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "optional": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.0"
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "requires": {
+        "wrappy": "1"
+      }
+    },
+    "os-browserify": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+      "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+      "dev": true
+    },
+    "p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "requires": {
+        "p-try": "^2.0.0"
+      }
+    },
+    "p-locate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "requires": {
+        "p-limit": "^2.0.0"
+      }
+    },
+    "p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true
+    },
+    "pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+      "dev": true
+    },
+    "parallel-transform": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",
+      "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==",
+      "dev": true,
+      "requires": {
+        "cyclist": "^1.0.1",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.1.5"
+      }
+    },
+    "parents": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
+      "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=",
+      "dev": true,
+      "requires": {
+        "path-platform": "~0.11.15"
+      }
+    },
+    "parse-asn1": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
+      "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==",
+      "dev": true,
+      "requires": {
+        "asn1.js": "^4.0.0",
+        "browserify-aes": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "parse-passwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-browserify": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
+      "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
+      "dev": true
+    },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+      "dev": true,
+      "optional": true
+    },
+    "path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "dev": true
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
+    },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+      "dev": true
+    },
+    "path-platform": {
+      "version": "0.11.15",
+      "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz",
+      "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=",
+      "dev": true
+    },
+    "pbkdf2": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
+      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
+      "dev": true,
+      "requires": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "picomatch": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "dev": true,
+      "optional": true
+    },
+    "pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true
+    },
+    "pkg-dir": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+      "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+      "dev": true,
+      "requires": {
+        "find-up": "^3.0.0"
+      }
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
+    "process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+      "dev": true
+    },
+    "promise-inflight": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+      "dev": true
+    },
+    "prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "pumpify": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+      "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+      "dev": true,
+      "requires": {
+        "duplexify": "^3.6.0",
+        "inherits": "^2.0.3",
+        "pump": "^2.0.0"
+      },
+      "dependencies": {
+        "pump": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+          "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+          "dev": true,
+          "requires": {
+            "end-of-stream": "^1.1.0",
+            "once": "^1.3.1"
+          }
+        }
+      }
+    },
+    "punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+      "dev": true
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
+    },
+    "querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+      "dev": true
+    },
+    "randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "read-only-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
+      "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "dev": true,
+      "requires": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "readdirp": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
+      "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "picomatch": "^2.2.1"
+      }
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true,
+      "optional": true
+    },
+    "repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true
+    },
+    "require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+      "dev": true
+    },
+    "resolve": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+      "dev": true,
+      "requires": {
+        "path-parse": "^1.0.6"
+      }
+    },
+    "resolve-cwd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+      "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      }
+    },
+    "resolve-dir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "^2.0.0",
+        "global-modules": "^1.0.0"
+      },
+      "dependencies": {
+        "global-modules": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+          "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+          "dev": true,
+          "requires": {
+            "global-prefix": "^1.0.1",
+            "is-windows": "^1.0.1",
+            "resolve-dir": "^1.0.0"
+          }
+        }
+      }
+    },
+    "resolve-from": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+      "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.1.3"
+      }
+    },
+    "ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "run-queue": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+      "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "dev": true
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "~0.1.10"
+      }
+    },
+    "schema-utils": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+      "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.1.0",
+        "ajv-errors": "^1.0.0",
+        "ajv-keywords": "^3.1.0"
+      }
+    },
+    "semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true
+    },
+    "serialize-javascript": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz",
+      "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.1.0"
+      }
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "set-value": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "shasum": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz",
+      "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=",
+      "dev": true,
+      "requires": {
+        "json-stable-stringify": "~0.0.0",
+        "sha.js": "~2.4.4"
+      }
+    },
+    "shasum-object": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz",
+      "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==",
+      "dev": true,
+      "requires": {
+        "fast-safe-stringify": "^2.0.7"
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "^1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "shell-quote": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
+      "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
+      "dev": true
+    },
+    "simple-concat": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
+      "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=",
+      "dev": true
+    },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.2.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "source-list-map": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+      "dev": true
+    },
+    "source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "dev": true
+    },
+    "source-map-resolve": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+      "dev": true,
+      "requires": {
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "source-map-support": {
+      "version": "0.5.19",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.0"
+      }
+    },
+    "ssri": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
+      "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
+      "dev": true,
+      "requires": {
+        "figgy-pudding": "^3.5.1"
+      }
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "stream-browserify": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
+      "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
+      "dev": true,
+      "requires": {
+        "inherits": "~2.0.1",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "stream-combiner2": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+      "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=",
+      "dev": true,
+      "requires": {
+        "duplexer2": "~0.1.0",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "stream-each": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
+      "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "stream-http": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.1.1.tgz",
+      "integrity": "sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg==",
+      "dev": true,
+      "requires": {
+        "builtin-status-codes": "^3.0.0",
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "xtend": "^4.0.2"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "stream-shift": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+      "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
+      "dev": true
+    },
+    "stream-splicer": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz",
+      "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "string-width": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "dev": true,
+      "requires": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      }
+    },
+    "string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
+    "strip-ansi": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "^4.1.0"
+      }
+    },
+    "subarg": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+      "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.1.0"
+      }
+    },
+    "supports-color": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+      "dev": true,
+      "requires": {
+        "has-flag": "^3.0.0"
+      }
+    },
+    "syntax-error": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz",
+      "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==",
+      "dev": true,
+      "requires": {
+        "acorn-node": "^1.2.0"
+      }
+    },
+    "tapable": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+      "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
+      "dev": true
+    },
+    "terser": {
+      "version": "4.8.0",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
+      "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+      "dev": true,
+      "requires": {
+        "commander": "^2.20.0",
+        "source-map": "~0.6.1",
+        "source-map-support": "~0.5.12"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "terser-webpack-plugin": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz",
+      "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==",
+      "dev": true,
+      "requires": {
+        "cacache": "^12.0.2",
+        "find-cache-dir": "^2.1.0",
+        "is-wsl": "^1.1.0",
+        "schema-utils": "^1.0.0",
+        "serialize-javascript": "^3.1.0",
+        "source-map": "^0.6.1",
+        "terser": "^4.1.2",
+        "webpack-sources": "^1.4.0",
+        "worker-farm": "^1.7.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      }
+    },
+    "timers-browserify": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
+      "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=",
+      "dev": true,
+      "requires": {
+        "process": "~0.11.0"
+      }
+    },
+    "to-arraybuffer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+      "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+      "dev": true
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1"
+      }
+    },
+    "tslib": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+      "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+      "dev": true
+    },
+    "tty-browserify": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
+      "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
+      "dev": true
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "umd": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
+      "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==",
+      "dev": true
+    },
+    "undeclared-identifiers": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz",
+      "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==",
+      "dev": true,
+      "requires": {
+        "acorn-node": "^1.3.0",
+        "dash-ast": "^1.0.0",
+        "get-assigned-identifiers": "^1.2.0",
+        "simple-concat": "^1.0.0",
+        "xtend": "^4.0.1"
+      }
+    },
+    "union-value": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+      "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^2.0.1"
+      }
+    },
+    "unique-filename": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+      "dev": true,
+      "requires": {
+        "unique-slug": "^2.0.0"
+      }
+    },
+    "unique-slug": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "^0.1.4"
+      }
+    },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "^2.0.3",
+            "has-values": "^0.1.4",
+            "isobject": "^2.0.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        }
+      }
+    },
+    "upath": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+      "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+      "dev": true,
+      "optional": true
+    },
+    "uri-js": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+      "dev": true,
+      "requires": {
+        "punycode": "^2.1.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+          "dev": true
+        }
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+          "dev": true
+        }
+      }
+    },
+    "use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true
+    },
+    "util": {
+      "version": "0.10.4",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+      "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+          "dev": true
+        }
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "v8-compile-cache": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
+      "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
+      "dev": true
+    },
+    "vm-browserify": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+      "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+      "dev": true
+    },
+    "watchpack": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz",
+      "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==",
+      "dev": true,
+      "requires": {
+        "chokidar": "^3.4.0",
+        "graceful-fs": "^4.1.2",
+        "neo-async": "^2.5.0",
+        "watchpack-chokidar2": "^2.0.0"
+      }
+    },
+    "watchpack-chokidar2": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz",
+      "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "chokidar": "^2.1.8"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "micromatch": "^3.1.4",
+            "normalize-path": "^2.1.1"
+          },
+          "dependencies": {
+            "normalize-path": {
+              "version": "2.1.1",
+              "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+              "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "remove-trailing-separator": "^1.0.1"
+              }
+            }
+          }
+        },
+        "binary-extensions": {
+          "version": "1.13.1",
+          "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+          "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+          "dev": true,
+          "optional": true
+        },
+        "chokidar": {
+          "version": "2.1.8",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+          "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "anymatch": "^2.0.0",
+            "async-each": "^1.0.1",
+            "braces": "^2.3.2",
+            "fsevents": "^1.2.7",
+            "glob-parent": "^3.1.0",
+            "inherits": "^2.0.3",
+            "is-binary-path": "^1.0.0",
+            "is-glob": "^4.0.0",
+            "normalize-path": "^3.0.0",
+            "path-is-absolute": "^1.0.0",
+            "readdirp": "^2.2.1",
+            "upath": "^1.1.1"
+          }
+        },
+        "fsevents": {
+          "version": "1.2.13",
+          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+          "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "bindings": "^1.5.0",
+            "nan": "^2.12.1"
+          }
+        },
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-glob": "^3.1.0",
+            "path-dirname": "^1.0.0"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "is-extglob": "^2.1.0"
+              }
+            }
+          }
+        },
+        "is-binary-path": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+          "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "binary-extensions": "^1.0.0"
+          }
+        },
+        "readdirp": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+          "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "graceful-fs": "^4.1.11",
+            "micromatch": "^3.1.10",
+            "readable-stream": "^2.0.2"
+          }
+        }
+      }
+    },
+    "webpack": {
+      "version": "4.43.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz",
+      "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-module-context": "1.9.0",
+        "@webassemblyjs/wasm-edit": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0",
+        "acorn": "^6.4.1",
+        "ajv": "^6.10.2",
+        "ajv-keywords": "^3.4.1",
+        "chrome-trace-event": "^1.0.2",
+        "enhanced-resolve": "^4.1.0",
+        "eslint-scope": "^4.0.3",
+        "json-parse-better-errors": "^1.0.2",
+        "loader-runner": "^2.4.0",
+        "loader-utils": "^1.2.3",
+        "memory-fs": "^0.4.1",
+        "micromatch": "^3.1.10",
+        "mkdirp": "^0.5.3",
+        "neo-async": "^2.6.1",
+        "node-libs-browser": "^2.2.1",
+        "schema-utils": "^1.0.0",
+        "tapable": "^1.1.3",
+        "terser-webpack-plugin": "^1.4.3",
+        "watchpack": "^1.6.1",
+        "webpack-sources": "^1.4.1"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "6.4.1",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
+          "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-cli": {
+      "version": "3.3.12",
+      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz",
+      "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2",
+        "cross-spawn": "^6.0.5",
+        "enhanced-resolve": "^4.1.1",
+        "findup-sync": "^3.0.0",
+        "global-modules": "^2.0.0",
+        "import-local": "^2.0.0",
+        "interpret": "^1.4.0",
+        "loader-utils": "^1.4.0",
+        "supports-color": "^6.1.0",
+        "v8-compile-cache": "^2.1.1",
+        "yargs": "^13.3.2"
+      }
+    },
+    "webpack-sources": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+      "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+      "dev": true,
+      "requires": {
+        "source-list-map": "^2.0.0",
+        "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "requires": {
+        "isexe": "^2.0.0"
+      }
+    },
+    "which-module": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "dev": true
+    },
+    "worker-farm": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+      "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
+      "dev": true,
+      "requires": {
+        "errno": "~0.1.7"
+      }
+    },
+    "wrap-ansi": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^3.2.0",
+        "string-width": "^3.0.0",
+        "strip-ansi": "^5.0.0"
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "xhr2": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.0.tgz",
+      "integrity": "sha512-BDtiD0i2iKPK/S8OAZfpk6tyzEDnKKSjxWHcMBVmh+LuqJ8A32qXTyOx+TVOg2dKvq6zGBq2sgKPkEeRs1qTRA=="
+    },
+    "xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true
+    },
+    "y18n": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+      "dev": true
+    },
+    "yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    },
+    "yargs": {
+      "version": "13.3.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+      "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+      "dev": true,
+      "requires": {
+        "cliui": "^5.0.0",
+        "find-up": "^3.0.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^3.0.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^13.1.2"
+      }
+    },
+    "yargs-parser": {
+      "version": "13.1.2",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+      "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+      "dev": true,
+      "requires": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      }
+    }
+  }
+}
diff --git a/custos-client-sdks/custos-js-sdk/package.json b/custos-client-sdks/custos-js-sdk/package.json
new file mode 100644
index 0000000..30e25a0
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/package.json
@@ -0,0 +1,13 @@
+{
+  "name": "grpc-web-custos-sdk",
+  "dependencies": {
+    "google-protobuf": "^3.12.2",
+    "grpc-web": "^1.2.0",
+    "xhr2": "^0.2.0"
+  },
+  "devDependencies": {
+    "browserify": "^16.2.2",
+    "webpack": "^4.16.5",
+    "webpack-cli": "^3.1.0"
+  }
+}
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/agent-profile-service/AgentProfileService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/agent-profile-service/AgentProfileService_pb.js
new file mode 100644
index 0000000..5454d03
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/agent-profile-service/AgentProfileService_pb.js
@@ -0,0 +1,968 @@
+// source: src/main/proto/AgentProfileService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.org.apache.custos.agent.profile.service.Agent', null, global);
+goog.exportSymbol('proto.org.apache.custos.agent.profile.service.AgentAttribute', null, global);
+goog.exportSymbol('proto.org.apache.custos.agent.profile.service.AgentRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.agent.profile.service.AgentStatus', null, global);
+goog.exportSymbol('proto.org.apache.custos.agent.profile.service.OperationStatus', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.agent.profile.service.Agent = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.agent.profile.service.Agent.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.agent.profile.service.Agent, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.agent.profile.service.Agent.displayName = 'proto.org.apache.custos.agent.profile.service.Agent';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.agent.profile.service.AgentAttribute.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.agent.profile.service.AgentAttribute, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.agent.profile.service.AgentAttribute.displayName = 'proto.org.apache.custos.agent.profile.service.AgentAttribute';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.agent.profile.service.AgentRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.agent.profile.service.AgentRequest.displayName = 'proto.org.apache.custos.agent.profile.service.AgentRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.agent.profile.service.OperationStatus = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.agent.profile.service.OperationStatus, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.agent.profile.service.OperationStatus.displayName = 'proto.org.apache.custos.agent.profile.service.OperationStatus';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.agent.profile.service.Agent.repeatedFields_ = [5,6];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.agent.profile.service.Agent.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.agent.profile.service.Agent} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.profile.service.Agent.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    status: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    createdAt: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    lastModifiedAt: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    rolesList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
+    attributesList: jspb.Message.toObjectList(msg.getAttributesList(),
+    proto.org.apache.custos.agent.profile.service.AgentAttribute.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.agent.profile.service.Agent;
+  return proto.org.apache.custos.agent.profile.service.Agent.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.agent.profile.service.Agent} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {!proto.org.apache.custos.agent.profile.service.AgentStatus} */ (reader.readEnum());
+      msg.setStatus(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setCreatedAt(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setLastModifiedAt(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRoles(value);
+      break;
+    case 6:
+      var value = new proto.org.apache.custos.agent.profile.service.AgentAttribute;
+      reader.readMessage(value,proto.org.apache.custos.agent.profile.service.AgentAttribute.deserializeBinaryFromReader);
+      msg.addAttributes(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.agent.profile.service.Agent.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.agent.profile.service.Agent} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.profile.service.Agent.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getStatus();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      2,
+      f
+    );
+  }
+  f = message.getCreatedAt();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getLastModifiedAt();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+  f = message.getRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      5,
+      f
+    );
+  }
+  f = message.getAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      6,
+      f,
+      proto.org.apache.custos.agent.profile.service.AgentAttribute.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent} returns this
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional AgentStatus status = 2;
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentStatus}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.getStatus = function() {
+  return /** @type {!proto.org.apache.custos.agent.profile.service.AgentStatus} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.profile.service.AgentStatus} value
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent} returns this
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3EnumField(this, 2, value);
+};
+
+
+/**
+ * optional int64 created_at = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.getCreatedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent} returns this
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.setCreatedAt = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional int64 last_modified_at = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.getLastModifiedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent} returns this
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.setLastModifiedAt = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * repeated string roles = 5;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.getRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 5));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent} returns this
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.setRolesList = function(value) {
+  return jspb.Message.setField(this, 5, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent} returns this
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.addRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent} returns this
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.clearRolesList = function() {
+  return this.setRolesList([]);
+};
+
+
+/**
+ * repeated AgentAttribute attributes = 6;
+ * @return {!Array<!proto.org.apache.custos.agent.profile.service.AgentAttribute>}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.getAttributesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.agent.profile.service.AgentAttribute>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.agent.profile.service.AgentAttribute, 6));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.agent.profile.service.AgentAttribute>} value
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent} returns this
+*/
+proto.org.apache.custos.agent.profile.service.Agent.prototype.setAttributesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 6, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.profile.service.AgentAttribute=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentAttribute}
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.addAttributes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.org.apache.custos.agent.profile.service.AgentAttribute, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.agent.profile.service.Agent} returns this
+ */
+proto.org.apache.custos.agent.profile.service.Agent.prototype.clearAttributesList = function() {
+  return this.setAttributesList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.repeatedFields_ = [3];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.agent.profile.service.AgentAttribute.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.agent.profile.service.AgentAttribute} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    key: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    valueList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentAttribute}
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.agent.profile.service.AgentAttribute;
+  return proto.org.apache.custos.agent.profile.service.AgentAttribute.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.agent.profile.service.AgentAttribute} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentAttribute}
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setKey(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.agent.profile.service.AgentAttribute.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.agent.profile.service.AgentAttribute} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getKey();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getValueList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentAttribute} returns this
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string key = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.getKey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentAttribute} returns this
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.setKey = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string value = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.getValueList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentAttribute} returns this
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.setValueList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentAttribute} returns this
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.addValue = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentAttribute} returns this
+ */
+proto.org.apache.custos.agent.profile.service.AgentAttribute.prototype.clearValueList = function() {
+  return this.setValueList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.agent.profile.service.AgentRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.agent.profile.service.AgentRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    agent: (f = msg.getAgent()) && proto.org.apache.custos.agent.profile.service.Agent.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentRequest}
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.agent.profile.service.AgentRequest;
+  return proto.org.apache.custos.agent.profile.service.AgentRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.agent.profile.service.AgentRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentRequest}
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = new proto.org.apache.custos.agent.profile.service.Agent;
+      reader.readMessage(value,proto.org.apache.custos.agent.profile.service.Agent.deserializeBinaryFromReader);
+      msg.setAgent(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.agent.profile.service.AgentRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.agent.profile.service.AgentRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAgent();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.org.apache.custos.agent.profile.service.Agent.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentRequest} returns this
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional Agent agent = 2;
+ * @return {?proto.org.apache.custos.agent.profile.service.Agent}
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.prototype.getAgent = function() {
+  return /** @type{?proto.org.apache.custos.agent.profile.service.Agent} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.agent.profile.service.Agent, 2));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.agent.profile.service.Agent|undefined} value
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentRequest} returns this
+*/
+proto.org.apache.custos.agent.profile.service.AgentRequest.prototype.setAgent = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.agent.profile.service.AgentRequest} returns this
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.prototype.clearAgent = function() {
+  return this.setAgent(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.agent.profile.service.AgentRequest.prototype.hasAgent = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.agent.profile.service.OperationStatus.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.agent.profile.service.OperationStatus.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.agent.profile.service.OperationStatus} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.profile.service.OperationStatus.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    status: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.agent.profile.service.OperationStatus}
+ */
+proto.org.apache.custos.agent.profile.service.OperationStatus.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.agent.profile.service.OperationStatus;
+  return proto.org.apache.custos.agent.profile.service.OperationStatus.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.agent.profile.service.OperationStatus} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.agent.profile.service.OperationStatus}
+ */
+proto.org.apache.custos.agent.profile.service.OperationStatus.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setStatus(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.agent.profile.service.OperationStatus.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.agent.profile.service.OperationStatus.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.agent.profile.service.OperationStatus} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.profile.service.OperationStatus.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getStatus();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool status = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.agent.profile.service.OperationStatus.prototype.getStatus = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.agent.profile.service.OperationStatus} returns this
+ */
+proto.org.apache.custos.agent.profile.service.OperationStatus.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.agent.profile.service.AgentStatus = {
+  ENABLED: 0,
+  DISABLED: 1
+};
+
+goog.object.extend(exports, proto.org.apache.custos.agent.profile.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/cluster-management-service/ClusterManagementService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/cluster-management-service/ClusterManagementService_pb.js
new file mode 100644
index 0000000..cb87bea
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/cluster-management-service/ClusterManagementService_pb.js
@@ -0,0 +1,349 @@
+// source: src/main/proto/ClusterManagementService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.displayName = 'proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.displayName = 'proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    secretname: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    namespace: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest;
+  return proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSecretname(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setNamespace(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSecretname();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getNamespace();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string secretName = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.prototype.getSecretname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest} returns this
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.prototype.setSecretname = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string namespace = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.prototype.getNamespace = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest} returns this
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateRequest.prototype.setNamespace = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    certificate: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse;
+  return proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCertificate(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getCertificate();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string certificate = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.prototype.getCertificate = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse} returns this
+ */
+proto.org.apache.custos.cluster.management.service.GetServerCertificateResponse.prototype.setCertificate = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+goog.object.extend(exports, proto.org.apache.custos.cluster.management.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/credential-store-service/CredentialStoreService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/credential-store-service/CredentialStoreService_pb.js
new file mode 100644
index 0000000..1c30eb6
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/credential-store-service/CredentialStoreService_pb.js
@@ -0,0 +1,2996 @@
+// source: src/main/proto/CredentialStoreService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.CredentialMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.Credentials', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.DeleteCredentialRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.GetCredentialRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.GetOwnerIdResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.OperationMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.OperationStatus', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.TokenRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.credential.store.service.Type', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.CredentialMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.CredentialMetadata.displayName = 'proto.org.apache.custos.credential.store.service.CredentialMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.GetCredentialRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.GetCredentialRequest.displayName = 'proto.org.apache.custos.credential.store.service.GetCredentialRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.displayName = 'proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.displayName = 'proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.OperationStatus = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.OperationStatus, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.OperationStatus.displayName = 'proto.org.apache.custos.credential.store.service.OperationStatus';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.DeleteCredentialRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.displayName = 'proto.org.apache.custos.credential.store.service.DeleteCredentialRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.displayName = 'proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.OperationMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.OperationMetadata.displayName = 'proto.org.apache.custos.credential.store.service.OperationMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.displayName = 'proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.displayName = 'proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.displayName = 'proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.TokenRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.TokenRequest.displayName = 'proto.org.apache.custos.credential.store.service.TokenRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.GetOwnerIdResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.GetOwnerIdResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.displayName = 'proto.org.apache.custos.credential.store.service.GetOwnerIdResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.credential.store.service.Credentials = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.credential.store.service.Credentials, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.credential.store.service.Credentials.displayName = 'proto.org.apache.custos.credential.store.service.Credentials';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.CredentialMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.CredentialMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    ownerid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    id: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    secret: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientsecretexpiredat: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    clientidissuedat: jspb.Message.getFieldWithDefault(msg, 5, 0),
+    type: jspb.Message.getFieldWithDefault(msg, 6, 0),
+    superTenant: jspb.Message.getBooleanFieldWithDefault(msg, 7, false),
+    superAdmin: jspb.Message.getBooleanFieldWithDefault(msg, 8, false),
+    internalSec: jspb.Message.getFieldWithDefault(msg, 11, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.CredentialMetadata;
+  return proto.org.apache.custos.credential.store.service.CredentialMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.CredentialMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setOwnerid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSecret(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setClientsecretexpiredat(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setClientidissuedat(value);
+      break;
+    case 6:
+      var value = /** @type {!proto.org.apache.custos.credential.store.service.Type} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    case 7:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setSuperTenant(value);
+      break;
+    case 8:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setSuperAdmin(value);
+      break;
+    case 11:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setInternalSec(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.CredentialMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.CredentialMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOwnerid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientsecretexpiredat();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+  f = message.getClientidissuedat();
+  if (f !== 0) {
+    writer.writeInt64(
+      5,
+      f
+    );
+  }
+  f = message.getType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      6,
+      f
+    );
+  }
+  f = message.getSuperTenant();
+  if (f) {
+    writer.writeBool(
+      7,
+      f
+    );
+  }
+  f = message.getSuperAdmin();
+  if (f) {
+    writer.writeBool(
+      8,
+      f
+    );
+  }
+  f = message.getInternalSec();
+  if (f.length > 0) {
+    writer.writeString(
+      11,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 ownerId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.getOwnerid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.setOwnerid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string id = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string secret = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.getSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.setSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional int64 clientSecretExpiredAt = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.getClientsecretexpiredat = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.setClientsecretexpiredat = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional int64 clientIdIssuedAt = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.getClientidissuedat = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.setClientidissuedat = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+/**
+ * optional Type type = 6;
+ * @return {!proto.org.apache.custos.credential.store.service.Type}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.getType = function() {
+  return /** @type {!proto.org.apache.custos.credential.store.service.Type} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.credential.store.service.Type} value
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.setType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 6, value);
+};
+
+
+/**
+ * optional bool super_tenant = 7;
+ * @return {boolean}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.getSuperTenant = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 7, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.setSuperTenant = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 7, value);
+};
+
+
+/**
+ * optional bool super_admin = 8;
+ * @return {boolean}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.getSuperAdmin = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 8, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.setSuperAdmin = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 8, value);
+};
+
+
+/**
+ * optional string internal_sec = 11;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.getInternalSec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 11, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.CredentialMetadata.prototype.setInternalSec = function(value) {
+  return jspb.Message.setProto3StringField(this, 11, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.GetCredentialRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.GetCredentialRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    ownerid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    id: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    type: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.GetCredentialRequest}
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.GetCredentialRequest;
+  return proto.org.apache.custos.credential.store.service.GetCredentialRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.GetCredentialRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.GetCredentialRequest}
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setOwnerid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 3:
+      var value = /** @type {!proto.org.apache.custos.credential.store.service.Type} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.GetCredentialRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.GetCredentialRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOwnerid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 ownerId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.prototype.getOwnerid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetCredentialRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.prototype.setOwnerid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string id = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetCredentialRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional Type type = 3;
+ * @return {!proto.org.apache.custos.credential.store.service.Type}
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.prototype.getType = function() {
+  return /** @type {!proto.org.apache.custos.credential.store.service.Type} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.credential.store.service.Type} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetCredentialRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetCredentialRequest.prototype.setType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    ownerid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest;
+  return proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setOwnerid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOwnerid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 ownerId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.prototype.getOwnerid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsRequest.prototype.setOwnerid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    secretlistList: jspb.Message.toObjectList(msg.getSecretlistList(),
+    proto.org.apache.custos.credential.store.service.CredentialMetadata.toObject, includeInstance),
+    requesteruseremail: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    requesterusername: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse;
+  return proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.credential.store.service.CredentialMetadata;
+      reader.readMessage(value,proto.org.apache.custos.credential.store.service.CredentialMetadata.deserializeBinaryFromReader);
+      msg.addSecretlist(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRequesteruseremail(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRequesterusername(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSecretlistList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.credential.store.service.CredentialMetadata.serializeBinaryToWriter
+    );
+  }
+  f = message.getRequesteruseremail();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getRequesterusername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated CredentialMetadata secretList = 1;
+ * @return {!Array<!proto.org.apache.custos.credential.store.service.CredentialMetadata>}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.getSecretlistList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.credential.store.service.CredentialMetadata>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.credential.store.service.CredentialMetadata, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.credential.store.service.CredentialMetadata>} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse} returns this
+*/
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.setSecretlistList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.credential.store.service.CredentialMetadata=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.credential.store.service.CredentialMetadata}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.addSecretlist = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.credential.store.service.CredentialMetadata, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.clearSecretlistList = function() {
+  return this.setSecretlistList([]);
+};
+
+
+/**
+ * optional string requesterUserEmail = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.getRequesteruseremail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.setRequesteruseremail = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string requesterUsername = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.getRequesterusername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetAllCredentialsResponse.prototype.setRequesterusername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.OperationStatus.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.OperationStatus.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.OperationStatus} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.OperationStatus.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    state: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.OperationStatus}
+ */
+proto.org.apache.custos.credential.store.service.OperationStatus.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.OperationStatus;
+  return proto.org.apache.custos.credential.store.service.OperationStatus.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.OperationStatus} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.OperationStatus}
+ */
+proto.org.apache.custos.credential.store.service.OperationStatus.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setState(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.OperationStatus.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.OperationStatus.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.OperationStatus} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.OperationStatus.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getState();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool state = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.credential.store.service.OperationStatus.prototype.getState = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.credential.store.service.OperationStatus} returns this
+ */
+proto.org.apache.custos.credential.store.service.OperationStatus.prototype.setState = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.DeleteCredentialRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    ownerid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    type: jspb.Message.getFieldWithDefault(msg, 2, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.DeleteCredentialRequest}
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.DeleteCredentialRequest;
+  return proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.DeleteCredentialRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.DeleteCredentialRequest}
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setOwnerid(value);
+      break;
+    case 2:
+      var value = /** @type {!proto.org.apache.custos.credential.store.service.Type} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.DeleteCredentialRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOwnerid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 ownerId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.prototype.getOwnerid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.DeleteCredentialRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.prototype.setOwnerid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional Type type = 2;
+ * @return {!proto.org.apache.custos.credential.store.service.Type}
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.prototype.getType = function() {
+  return /** @type {!proto.org.apache.custos.credential.store.service.Type} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.credential.store.service.Type} value
+ * @return {!proto.org.apache.custos.credential.store.service.DeleteCredentialRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.DeleteCredentialRequest.prototype.setType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    traceid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest;
+  return proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTraceid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTraceid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 traceId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.prototype.getTraceid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataRequest.prototype.setTraceid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.OperationMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.OperationMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    event: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    status: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    timestamp: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.OperationMetadata}
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.OperationMetadata;
+  return proto.org.apache.custos.credential.store.service.OperationMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.OperationMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.OperationMetadata}
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEvent(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setStatus(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTimestamp(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.OperationMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.OperationMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getEvent();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getStatus();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTimestamp();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string event = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.getEvent = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.setEvent = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string status = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.getStatus = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string timeStamp = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.getTimestamp = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.setTimestamp = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string performedBy = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.credential.store.service.OperationMetadata.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadataList: jspb.Message.toObjectList(msg.getMetadataList(),
+    proto.org.apache.custos.credential.store.service.OperationMetadata.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse;
+  return proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.credential.store.service.OperationMetadata;
+      reader.readMessage(value,proto.org.apache.custos.credential.store.service.OperationMetadata.deserializeBinaryFromReader);
+      msg.addMetadata(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadataList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.credential.store.service.OperationMetadata.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated OperationMetadata metadata = 1;
+ * @return {!Array<!proto.org.apache.custos.credential.store.service.OperationMetadata>}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.prototype.getMetadataList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.credential.store.service.OperationMetadata>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.credential.store.service.OperationMetadata, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.credential.store.service.OperationMetadata>} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse} returns this
+*/
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.prototype.setMetadataList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.credential.store.service.OperationMetadata=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.credential.store.service.OperationMetadata}
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.prototype.addMetadata = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.credential.store.service.OperationMetadata, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetOperationsMetadataResponse.prototype.clearMetadataList = function() {
+  return this.setMetadataList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    ownerid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    performedby: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest;
+  return proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setOwnerid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOwnerid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 ownerId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.prototype.getOwnerid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.prototype.setOwnerid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string performedBy = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse;
+  return proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string clientId = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string clientSecret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.TokenRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.TokenRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    token: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    parentclientid: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.TokenRequest}
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.TokenRequest;
+  return proto.org.apache.custos.credential.store.service.TokenRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.TokenRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.TokenRequest}
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setToken(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setParentclientid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.TokenRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.TokenRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getToken();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getParentclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string token = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.prototype.getToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.TokenRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.prototype.setToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string parentClientId = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.prototype.getParentclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.TokenRequest} returns this
+ */
+proto.org.apache.custos.credential.store.service.TokenRequest.prototype.setParentclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.GetOwnerIdResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    ownerid: jspb.Message.getFieldWithDefault(msg, 2, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.GetOwnerIdResponse}
+ */
+proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.GetOwnerIdResponse;
+  return proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.GetOwnerIdResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.GetOwnerIdResponse}
+ */
+proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setOwnerid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.GetOwnerIdResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOwnerid();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 ownerId = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.prototype.getOwnerid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.GetOwnerIdResponse} returns this
+ */
+proto.org.apache.custos.credential.store.service.GetOwnerIdResponse.prototype.setOwnerid = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.credential.store.service.Credentials.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.credential.store.service.Credentials} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.Credentials.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    iamClientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    iamClientSecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    ciLogonClientId: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    ciLogonClientSecret: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    custosClientId: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    custosClientSecret: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    custosClientIdIssuedAt: jspb.Message.getFloatingPointFieldWithDefault(msg, 7, 0.0),
+    custosClientSecretExpiredAt: jspb.Message.getFloatingPointFieldWithDefault(msg, 8, 0.0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.credential.store.service.Credentials;
+  return proto.org.apache.custos.credential.store.service.Credentials.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.credential.store.service.Credentials} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamClientSecret(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCiLogonClientId(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCiLogonClientSecret(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCustosClientId(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCustosClientSecret(value);
+      break;
+    case 7:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setCustosClientIdIssuedAt(value);
+      break;
+    case 8:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setCustosClientSecretExpiredAt(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.credential.store.service.Credentials.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.credential.store.service.Credentials} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.credential.store.service.Credentials.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getIamClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getIamClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getCiLogonClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getCiLogonClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getCustosClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getCustosClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getCustosClientIdIssuedAt();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      7,
+      f
+    );
+  }
+  f = message.getCustosClientSecretExpiredAt();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string iam_client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.getIamClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials} returns this
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.setIamClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string iam_client_secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.getIamClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials} returns this
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.setIamClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string ci_logon_client_id = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.getCiLogonClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials} returns this
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.setCiLogonClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string ci_logon_client_secret = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.getCiLogonClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials} returns this
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.setCiLogonClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string custos_client_id = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.getCustosClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials} returns this
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.setCustosClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string custos_client_secret = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.getCustosClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials} returns this
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.setCustosClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional double custos_client_id_issued_at = 7;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.getCustosClientIdIssuedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 7, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials} returns this
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.setCustosClientIdIssuedAt = function(value) {
+  return jspb.Message.setProto3FloatField(this, 7, value);
+};
+
+
+/**
+ * optional double custos_client_secret_expired_at = 8;
+ * @return {number}
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.getCustosClientSecretExpiredAt = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 8, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.credential.store.service.Credentials} returns this
+ */
+proto.org.apache.custos.credential.store.service.Credentials.prototype.setCustosClientSecretExpiredAt = function(value) {
+  return jspb.Message.setProto3FloatField(this, 8, value);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.credential.store.service.Type = {
+  CUSTOS: 0,
+  IAM: 1,
+  CILOGON: 2,
+  INDIVIDUAL: 3,
+  AGENT_CLIENT: 4,
+  AGENT: 5
+};
+
+goog.object.extend(exports, proto.org.apache.custos.credential.store.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/federated-authentication-service/FederatedAuthenticationService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/federated-authentication-service/FederatedAuthenticationService_pb.js
new file mode 100644
index 0000000..7029434
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/federated-authentication-service/FederatedAuthenticationService_pb.js
@@ -0,0 +1,2322 @@
+// source: src/main/proto/FederatedAuthenticationService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.org.apache.custos.federated.authentication.service.ClientMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.federated.authentication.service.DeleteClientRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.federated.authentication.service.Empty', null, global);
+goog.exportSymbol('proto.org.apache.custos.federated.authentication.service.GetClientRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.federated.authentication.service.GetClientResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.federated.authentication.service.OperationMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.federated.authentication.service.RegisterClientResponse', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.federated.authentication.service.ClientMetadata.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.federated.authentication.service.ClientMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.federated.authentication.service.ClientMetadata.displayName = 'proto.org.apache.custos.federated.authentication.service.ClientMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.federated.authentication.service.RegisterClientResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.displayName = 'proto.org.apache.custos.federated.authentication.service.RegisterClientResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.federated.authentication.service.GetClientRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.federated.authentication.service.GetClientRequest.displayName = 'proto.org.apache.custos.federated.authentication.service.GetClientRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.federated.authentication.service.GetClientResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.federated.authentication.service.GetClientResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.federated.authentication.service.GetClientResponse.displayName = 'proto.org.apache.custos.federated.authentication.service.GetClientResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.federated.authentication.service.DeleteClientRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.displayName = 'proto.org.apache.custos.federated.authentication.service.DeleteClientRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.federated.authentication.service.Empty = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.federated.authentication.service.Empty, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.federated.authentication.service.Empty.displayName = 'proto.org.apache.custos.federated.authentication.service.Empty';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.displayName = 'proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.federated.authentication.service.OperationMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.federated.authentication.service.OperationMetadata.displayName = 'proto.org.apache.custos.federated.authentication.service.OperationMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.displayName = 'proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.repeatedFields_ = [3,5,7];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.federated.authentication.service.ClientMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    tenantname: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    scopeList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    tenanturi: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    contactsList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
+    comment: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    redirecturisList: (f = jspb.Message.getRepeatedField(msg, 7)) == null ? undefined : f,
+    clientid: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 9, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.federated.authentication.service.ClientMetadata;
+  return proto.org.apache.custos.federated.authentication.service.ClientMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTenantname(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addScope(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTenanturi(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addContacts(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setComment(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRedirecturis(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.federated.authentication.service.ClientMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getTenantname();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getScopeList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getTenanturi();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getContactsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      5,
+      f
+    );
+  }
+  f = message.getComment();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getRedirecturisList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      7,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      9,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string tenantName = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.getTenantname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.setTenantname = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string scope = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.getScopeList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.setScopeList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.addScope = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.clearScopeList = function() {
+  return this.setScopeList([]);
+};
+
+
+/**
+ * optional string tenantURI = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.getTenanturi = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.setTenanturi = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * repeated string contacts = 5;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.getContactsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 5));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.setContactsList = function(value) {
+  return jspb.Message.setField(this, 5, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.addContacts = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.clearContactsList = function() {
+  return this.setContactsList([]);
+};
+
+
+/**
+ * optional string comment = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.getComment = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.setComment = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * repeated string redirectURIs = 7;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.getRedirecturisList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 7));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.setRedirecturisList = function(value) {
+  return jspb.Message.setField(this, 7, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.addRedirecturis = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 7, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.clearRedirecturisList = function() {
+  return this.setRedirecturisList([]);
+};
+
+
+/**
+ * optional string clientId = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional string performedBy = 9;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.ClientMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.ClientMetadata.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 9, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    clientidissuedat: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    clientsecretexpiresat: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    clientregistrationuri: jspb.Message.getFieldWithDefault(msg, 5, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse}
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.federated.authentication.service.RegisterClientResponse;
+  return proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse}
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setClientidissuedat(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setClientsecretexpiresat(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientregistrationuri(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getClientidissuedat();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getClientsecretexpiresat();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+  f = message.getClientregistrationuri();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string clientId = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string clientSecret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 clientIdIssuedAt = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.getClientidissuedat = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.setClientidissuedat = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional int64 clientSecretExpiresAt = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.getClientsecretexpiresat = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.setClientsecretexpiresat = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional string clientRegistrationUri = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.getClientregistrationuri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.RegisterClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.RegisterClientResponse.prototype.setClientregistrationuri = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.federated.authentication.service.GetClientRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetClientRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    clientid: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientRequest}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.federated.authentication.service.GetClientRequest;
+  return proto.org.apache.custos.federated.authentication.service.GetClientRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetClientRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientRequest}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.federated.authentication.service.GetClientRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetClientRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientRequest} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string clientId = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientRequest} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.repeatedFields_ = [3,4,5];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.federated.authentication.service.GetClientResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientname: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    redirecturisList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    granttypesList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f,
+    scopeList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
+    clientidissuedat: jspb.Message.getFieldWithDefault(msg, 6, 0),
+    comment: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    clientsecretexpiresat: jspb.Message.getFieldWithDefault(msg, 9, 0),
+    clientregistrationuri: jspb.Message.getFieldWithDefault(msg, 10, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.federated.authentication.service.GetClientResponse;
+  return proto.org.apache.custos.federated.authentication.service.GetClientResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientname(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRedirecturis(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addGranttypes(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addScope(value);
+      break;
+    case 6:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setClientidissuedat(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setComment(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    case 9:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setClientsecretexpiresat(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientregistrationuri(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.federated.authentication.service.GetClientResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientname();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getRedirecturisList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getGranttypesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      4,
+      f
+    );
+  }
+  f = message.getScopeList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      5,
+      f
+    );
+  }
+  f = message.getClientidissuedat();
+  if (f !== 0) {
+    writer.writeInt64(
+      6,
+      f
+    );
+  }
+  f = message.getComment();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getClientsecretexpiresat();
+  if (f !== 0) {
+    writer.writeInt64(
+      9,
+      f
+    );
+  }
+  f = message.getClientregistrationuri();
+  if (f.length > 0) {
+    writer.writeString(
+      10,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string clientId = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string clientName = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getClientname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setClientname = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string redirectURIs = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getRedirecturisList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setRedirecturisList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.addRedirecturis = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.clearRedirecturisList = function() {
+  return this.setRedirecturisList([]);
+};
+
+
+/**
+ * repeated string grantTypes = 4;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getGranttypesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 4));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setGranttypesList = function(value) {
+  return jspb.Message.setField(this, 4, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.addGranttypes = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.clearGranttypesList = function() {
+  return this.setGranttypesList([]);
+};
+
+
+/**
+ * repeated string scope = 5;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getScopeList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 5));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setScopeList = function(value) {
+  return jspb.Message.setField(this, 5, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.addScope = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.clearScopeList = function() {
+  return this.setScopeList([]);
+};
+
+
+/**
+ * optional int64 clientIdIssuedAt = 6;
+ * @return {number}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getClientidissuedat = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setClientidissuedat = function(value) {
+  return jspb.Message.setProto3IntField(this, 6, value);
+};
+
+
+/**
+ * optional string comment = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getComment = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setComment = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string clientSecret = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional int64 clientSecretExpiresAt = 9;
+ * @return {number}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getClientsecretexpiresat = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setClientsecretexpiresat = function(value) {
+  return jspb.Message.setProto3IntField(this, 9, value);
+};
+
+
+/**
+ * optional string clientRegistrationUri = 10;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.getClientregistrationuri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 10, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetClientResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetClientResponse.prototype.setClientregistrationuri = function(value) {
+  return jspb.Message.setProto3StringField(this, 10, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.federated.authentication.service.DeleteClientRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    clientid: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.federated.authentication.service.DeleteClientRequest}
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.federated.authentication.service.DeleteClientRequest;
+  return proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.federated.authentication.service.DeleteClientRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.federated.authentication.service.DeleteClientRequest}
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.federated.authentication.service.DeleteClientRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.DeleteClientRequest} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string clientId = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.DeleteClientRequest} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string performedBy = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.DeleteClientRequest} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.DeleteClientRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.federated.authentication.service.Empty.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.federated.authentication.service.Empty.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.federated.authentication.service.Empty} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.Empty.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.federated.authentication.service.Empty}
+ */
+proto.org.apache.custos.federated.authentication.service.Empty.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.federated.authentication.service.Empty;
+  return proto.org.apache.custos.federated.authentication.service.Empty.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.federated.authentication.service.Empty} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.federated.authentication.service.Empty}
+ */
+proto.org.apache.custos.federated.authentication.service.Empty.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.federated.authentication.service.Empty.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.federated.authentication.service.Empty.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.federated.authentication.service.Empty} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.Empty.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    traceid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest;
+  return proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTraceid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTraceid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 traceId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.prototype.getTraceid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.prototype.setTraceid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.federated.authentication.service.OperationMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.federated.authentication.service.OperationMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    event: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    status: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    timestamp: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.federated.authentication.service.OperationMetadata}
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.federated.authentication.service.OperationMetadata;
+  return proto.org.apache.custos.federated.authentication.service.OperationMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.federated.authentication.service.OperationMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.federated.authentication.service.OperationMetadata}
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEvent(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setStatus(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTimestamp(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.federated.authentication.service.OperationMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.federated.authentication.service.OperationMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getEvent();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getStatus();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTimestamp();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string event = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.getEvent = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.setEvent = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string status = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.getStatus = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string timeStamp = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.getTimestamp = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.setTimestamp = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string performedBy = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.OperationMetadata.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadataList: jspb.Message.toObjectList(msg.getMetadataList(),
+    proto.org.apache.custos.federated.authentication.service.OperationMetadata.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse;
+  return proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.federated.authentication.service.OperationMetadata;
+      reader.readMessage(value,proto.org.apache.custos.federated.authentication.service.OperationMetadata.deserializeBinaryFromReader);
+      msg.addMetadata(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadataList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.federated.authentication.service.OperationMetadata.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated OperationMetadata metadata = 1;
+ * @return {!Array<!proto.org.apache.custos.federated.authentication.service.OperationMetadata>}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.prototype.getMetadataList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.federated.authentication.service.OperationMetadata>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.federated.authentication.service.OperationMetadata, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.federated.authentication.service.OperationMetadata>} value
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse} returns this
+*/
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.prototype.setMetadataList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.federated.authentication.service.OperationMetadata=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.federated.authentication.service.OperationMetadata}
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.prototype.addMetadata = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.federated.authentication.service.OperationMetadata, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse} returns this
+ */
+proto.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.prototype.clearMetadataList = function() {
+  return this.setMetadataList([]);
+};
+
+
+goog.object.extend(exports, proto.org.apache.custos.federated.authentication.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/iam-admin-service/IamAdminService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/iam-admin-service/IamAdminService_pb.js
new file mode 100644
index 0000000..e6b5064
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/iam-admin-service/IamAdminService_pb.js
@@ -0,0 +1,11990 @@
+// source: src/main/proto/IamAdminService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+var google_protobuf_empty_pb = require('google-protobuf/google/protobuf/empty_pb.js');
+goog.object.extend(proto, google_protobuf_empty_pb);
+goog.exportSymbol('proto.org.apache.custos.iam.service.AddProtocolMapperRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.AddRolesRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.AddUserAttributesRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.AddUserResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.AddUserRolesRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.Agent', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.AgentClientMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.AllRoles', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.CheckingResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.ClaimJSONTypes', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.DeleteTenantRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.DeleteUserAttributeRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.DeleteUserRolesRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.EventPersistenceRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.FederateIDPResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.FederatedIDPs', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.FindUsersRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.FindUsersResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.GetAllResources', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.GetAllResourcesResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.GetOperationsMetadataRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.GetOperationsMetadataResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.GroupRepresentation', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.GroupRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.GroupsRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.GroupsResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.IsUsernameAvailableRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.MapperTypes', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.OperationMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.OperationStatus', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.RegisterUserRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.RegisterUserResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.RegisterUsersRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.RegisterUsersResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.ResetUserPassword', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.ResourceTypes', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.RoleRepresentation', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.SetUpTenantRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.SetUpTenantResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.UpdateUserProfileRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.UserAttribute', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.UserGroupMappingRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.UserRepresentation', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.UserSearchMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.iam.service.UserSearchRequest', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.SetUpTenantRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.SetUpTenantRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.SetUpTenantRequest.displayName = 'proto.org.apache.custos.iam.service.SetUpTenantRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.displayName = 'proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.FederateIDPResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.FederateIDPResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.FederateIDPResponse.displayName = 'proto.org.apache.custos.iam.service.FederateIDPResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.SetUpTenantResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.SetUpTenantResponse.displayName = 'proto.org.apache.custos.iam.service.SetUpTenantResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.IsUsernameAvailableRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.displayName = 'proto.org.apache.custos.iam.service.IsUsernameAvailableRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.CheckingResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.CheckingResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.CheckingResponse.displayName = 'proto.org.apache.custos.iam.service.CheckingResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.UserRepresentation = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.UserRepresentation.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.UserRepresentation, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.UserRepresentation.displayName = 'proto.org.apache.custos.iam.service.UserRepresentation';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.GroupRepresentation.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.GroupRepresentation, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.GroupRepresentation.displayName = 'proto.org.apache.custos.iam.service.GroupRepresentation';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.RegisterUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.RegisterUserRequest.displayName = 'proto.org.apache.custos.iam.service.RegisterUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.RegisterUsersRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.RegisterUsersRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.RegisterUsersRequest.displayName = 'proto.org.apache.custos.iam.service.RegisterUsersRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.RegisterUserResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.RegisterUserResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.RegisterUserResponse.displayName = 'proto.org.apache.custos.iam.service.RegisterUserResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.RegisterUsersResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.RegisterUsersResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.RegisterUsersResponse.displayName = 'proto.org.apache.custos.iam.service.RegisterUsersResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.UserSearchMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.UserSearchMetadata.displayName = 'proto.org.apache.custos.iam.service.UserSearchMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.FindUsersRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.FindUsersRequest.displayName = 'proto.org.apache.custos.iam.service.FindUsersRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.UserSearchRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.UserSearchRequest.displayName = 'proto.org.apache.custos.iam.service.UserSearchRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.FindUsersResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.FindUsersResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.FindUsersResponse.displayName = 'proto.org.apache.custos.iam.service.FindUsersResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.ResetUserPassword, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.ResetUserPassword.displayName = 'proto.org.apache.custos.iam.service.ResetUserPassword';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.DeleteUserRolesRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.DeleteUserRolesRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.DeleteUserRolesRequest.displayName = 'proto.org.apache.custos.iam.service.DeleteUserRolesRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.AddUserRolesRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.AddUserRolesRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.AddUserRolesRequest.displayName = 'proto.org.apache.custos.iam.service.AddUserRolesRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.UpdateUserProfileRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.UpdateUserProfileRequest.displayName = 'proto.org.apache.custos.iam.service.UpdateUserProfileRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.AddUserResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.AddUserResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.AddUserResponse.displayName = 'proto.org.apache.custos.iam.service.AddUserResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.GetOperationsMetadataRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.displayName = 'proto.org.apache.custos.iam.service.GetOperationsMetadataRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.OperationMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.OperationMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.OperationMetadata.displayName = 'proto.org.apache.custos.iam.service.OperationMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.GetOperationsMetadataResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.displayName = 'proto.org.apache.custos.iam.service.GetOperationsMetadataResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.DeleteTenantRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.DeleteTenantRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.DeleteTenantRequest.displayName = 'proto.org.apache.custos.iam.service.DeleteTenantRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.AddRolesRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.AddRolesRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.AddRolesRequest.displayName = 'proto.org.apache.custos.iam.service.AddRolesRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.RoleRepresentation, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.RoleRepresentation.displayName = 'proto.org.apache.custos.iam.service.RoleRepresentation';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.AllRoles = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.AllRoles.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.AllRoles, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.AllRoles.displayName = 'proto.org.apache.custos.iam.service.AllRoles';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.AddProtocolMapperRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.AddProtocolMapperRequest.displayName = 'proto.org.apache.custos.iam.service.AddProtocolMapperRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.OperationStatus = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.OperationStatus, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.OperationStatus.displayName = 'proto.org.apache.custos.iam.service.OperationStatus';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.AddUserAttributesRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.AddUserAttributesRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.AddUserAttributesRequest.displayName = 'proto.org.apache.custos.iam.service.AddUserAttributesRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.DeleteUserAttributeRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.displayName = 'proto.org.apache.custos.iam.service.DeleteUserAttributeRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.UserAttribute = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.UserAttribute.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.UserAttribute, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.UserAttribute.displayName = 'proto.org.apache.custos.iam.service.UserAttribute';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.EventPersistenceRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.EventPersistenceRequest.displayName = 'proto.org.apache.custos.iam.service.EventPersistenceRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.GroupsRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.GroupsRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.GroupsRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.GroupsRequest.displayName = 'proto.org.apache.custos.iam.service.GroupsRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.GroupRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.GroupRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.GroupRequest.displayName = 'proto.org.apache.custos.iam.service.GroupRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.GroupsResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.GroupsResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.GroupsResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.GroupsResponse.displayName = 'proto.org.apache.custos.iam.service.GroupsResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.UserGroupMappingRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.UserGroupMappingRequest.displayName = 'proto.org.apache.custos.iam.service.UserGroupMappingRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.AgentClientMetadata.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.AgentClientMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.AgentClientMetadata.displayName = 'proto.org.apache.custos.iam.service.AgentClientMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.Agent = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.Agent.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.Agent, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.Agent.displayName = 'proto.org.apache.custos.iam.service.Agent';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.GetAllResources = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.GetAllResources, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.GetAllResources.displayName = 'proto.org.apache.custos.iam.service.GetAllResources';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.iam.service.GetAllResourcesResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.iam.service.GetAllResourcesResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.iam.service.GetAllResourcesResponse.displayName = 'proto.org.apache.custos.iam.service.GetAllResourcesResponse';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.repeatedFields_ = [10];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.SetUpTenantRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.SetUpTenantRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    tenantname: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    adminusername: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    adminfirstname: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    adminlastname: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    adminemail: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    adminpassword: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    tenanturl: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    requesteremail: jspb.Message.getFieldWithDefault(msg, 9, ""),
+    redirecturisList: (f = jspb.Message.getRepeatedField(msg, 10)) == null ? undefined : f,
+    custosclientid: jspb.Message.getFieldWithDefault(msg, 11, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.SetUpTenantRequest;
+  return proto.org.apache.custos.iam.service.SetUpTenantRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.SetUpTenantRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTenantname(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminusername(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminfirstname(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminlastname(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminemail(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminpassword(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTenanturl(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRequesteremail(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRedirecturis(value);
+      break;
+    case 11:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCustosclientid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.SetUpTenantRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.SetUpTenantRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getTenantname();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getAdminusername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getAdminfirstname();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getAdminlastname();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getAdminemail();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getAdminpassword();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getTenanturl();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getRequesteremail();
+  if (f.length > 0) {
+    writer.writeString(
+      9,
+      f
+    );
+  }
+  f = message.getRedirecturisList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      10,
+      f
+    );
+  }
+  f = message.getCustosclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      11,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string tenantName = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getTenantname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setTenantname = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string adminUsername = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getAdminusername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setAdminusername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string adminFirstname = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getAdminfirstname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setAdminfirstname = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string adminLastname = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getAdminlastname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setAdminlastname = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string adminEmail = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getAdminemail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setAdminemail = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string adminPassword = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getAdminpassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setAdminpassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string tenantURL = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getTenanturl = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setTenanturl = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional string requesterEmail = 9;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getRequesteremail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setRequesteremail = function(value) {
+  return jspb.Message.setProto3StringField(this, 9, value);
+};
+
+
+/**
+ * repeated string redirectURIs = 10;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getRedirecturisList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 10));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setRedirecturisList = function(value) {
+  return jspb.Message.setField(this, 10, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.addRedirecturis = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 10, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.clearRedirecturisList = function() {
+  return this.setRedirecturisList([]);
+};
+
+
+/**
+ * optional string custosClientId = 11;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.getCustosclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 11, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantRequest.prototype.setCustosclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 11, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    type: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    clientid: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientsec: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    configmapMap: (f = msg.getConfigmapMap()) ? f.toObject(includeInstance, undefined) : [],
+    requesteremail: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    idpid: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    scope: jspb.Message.getFieldWithDefault(msg, 8, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest;
+  return proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {!proto.org.apache.custos.iam.service.FederatedIDPs} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsec(value);
+      break;
+    case 5:
+      var value = msg.getConfigmapMap();
+      reader.readMessage(value, function(message, reader) {
+        jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString, null, "", "");
+         });
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRequesteremail(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIdpid(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setScope(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      2,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientsec();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getConfigmapMap(true);
+  if (f && f.getLength() > 0) {
+    f.serializeBinary(5, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString);
+  }
+  f = message.getRequesteremail();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getIdpid();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getScope();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} returns this
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional FederatedIDPs type = 2;
+ * @return {!proto.org.apache.custos.iam.service.FederatedIDPs}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.getType = function() {
+  return /** @type {!proto.org.apache.custos.iam.service.FederatedIDPs} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.FederatedIDPs} value
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} returns this
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.setType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 2, value);
+};
+
+
+/**
+ * optional string clientID = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} returns this
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string clientSec = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.getClientsec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} returns this
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.setClientsec = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * map<string, string> configMap = 5;
+ * @param {boolean=} opt_noLazyCreate Do not create the map if
+ * empty, instead returning `undefined`
+ * @return {!jspb.Map<string,string>}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.getConfigmapMap = function(opt_noLazyCreate) {
+  return /** @type {!jspb.Map<string,string>} */ (
+      jspb.Message.getMapField(this, 5, opt_noLazyCreate,
+      null));
+};
+
+
+/**
+ * Clears values from the map. The map will be non-null.
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} returns this
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.clearConfigmapMap = function() {
+  this.getConfigmapMap().clear();
+  return this;};
+
+
+/**
+ * optional string requesterEmail = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.getRequesteremail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} returns this
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.setRequesteremail = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string idpId = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.getIdpid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} returns this
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.setIdpid = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string scope = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.getScope = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest} returns this
+ */
+proto.org.apache.custos.iam.service.ConfigureFederateIDPRequest.prototype.setScope = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.FederateIDPResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.FederateIDPResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.FederateIDPResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.FederateIDPResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    status: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.FederateIDPResponse}
+ */
+proto.org.apache.custos.iam.service.FederateIDPResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.FederateIDPResponse;
+  return proto.org.apache.custos.iam.service.FederateIDPResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.FederateIDPResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.FederateIDPResponse}
+ */
+proto.org.apache.custos.iam.service.FederateIDPResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setStatus(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.FederateIDPResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.FederateIDPResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.FederateIDPResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.FederateIDPResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getStatus();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool status = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.FederateIDPResponse.prototype.getStatus = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.FederateIDPResponse} returns this
+ */
+proto.org.apache.custos.iam.service.FederateIDPResponse.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.SetUpTenantResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.SetUpTenantResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantResponse}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.SetUpTenantResponse;
+  return proto.org.apache.custos.iam.service.SetUpTenantResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.SetUpTenantResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantResponse}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.SetUpTenantResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.SetUpTenantResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string clientId = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantResponse} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string clientSecret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.SetUpTenantResponse} returns this
+ */
+proto.org.apache.custos.iam.service.SetUpTenantResponse.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.IsUsernameAvailableRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.IsUsernameAvailableRequest}
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.IsUsernameAvailableRequest;
+  return proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.IsUsernameAvailableRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.IsUsernameAvailableRequest}
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.IsUsernameAvailableRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.IsUsernameAvailableRequest} returns this
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string accessToken = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.IsUsernameAvailableRequest} returns this
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string userName = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.IsUsernameAvailableRequest} returns this
+ */
+proto.org.apache.custos.iam.service.IsUsernameAvailableRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.CheckingResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.CheckingResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.CheckingResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.CheckingResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    isExist: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.CheckingResponse}
+ */
+proto.org.apache.custos.iam.service.CheckingResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.CheckingResponse;
+  return proto.org.apache.custos.iam.service.CheckingResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.CheckingResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.CheckingResponse}
+ */
+proto.org.apache.custos.iam.service.CheckingResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsExist(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.CheckingResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.CheckingResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.CheckingResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.CheckingResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getIsExist();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool is_exist = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.CheckingResponse.prototype.getIsExist = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.CheckingResponse} returns this
+ */
+proto.org.apache.custos.iam.service.CheckingResponse.prototype.setIsExist = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.repeatedFields_ = [9,10,11];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.UserRepresentation.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.UserRepresentation} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    firstName: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    lastName: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    password: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    email: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    temporaryPassword: jspb.Message.getBooleanFieldWithDefault(msg, 8, false),
+    realmRolesList: (f = jspb.Message.getRepeatedField(msg, 9)) == null ? undefined : f,
+    clientRolesList: (f = jspb.Message.getRepeatedField(msg, 10)) == null ? undefined : f,
+    attributesList: jspb.Message.toObjectList(msg.getAttributesList(),
+    proto.org.apache.custos.iam.service.UserAttribute.toObject, includeInstance),
+    state: jspb.Message.getFieldWithDefault(msg, 12, ""),
+    creationTime: jspb.Message.getFloatingPointFieldWithDefault(msg, 13, 0.0),
+    lastLoginAt: jspb.Message.getFloatingPointFieldWithDefault(msg, 14, 0.0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.UserRepresentation;
+  return proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.UserRepresentation} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFirstName(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLastName(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEmail(value);
+      break;
+    case 8:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setTemporaryPassword(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRealmRoles(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addClientRoles(value);
+      break;
+    case 11:
+      var value = new proto.org.apache.custos.iam.service.UserAttribute;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserAttribute.deserializeBinaryFromReader);
+      msg.addAttributes(value);
+      break;
+    case 12:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setState(value);
+      break;
+    case 13:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setCreationTime(value);
+      break;
+    case 14:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setLastLoginAt(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.UserRepresentation.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.UserRepresentation} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getFirstName();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getLastName();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getTemporaryPassword();
+  if (f) {
+    writer.writeBool(
+      8,
+      f
+    );
+  }
+  f = message.getRealmRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      9,
+      f
+    );
+  }
+  f = message.getClientRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      10,
+      f
+    );
+  }
+  f = message.getAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      11,
+      f,
+      proto.org.apache.custos.iam.service.UserAttribute.serializeBinaryToWriter
+    );
+  }
+  f = message.getState();
+  if (f.length > 0) {
+    writer.writeString(
+      12,
+      f
+    );
+  }
+  f = message.getCreationTime();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      13,
+      f
+    );
+  }
+  f = message.getLastLoginAt();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      14,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string username = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string first_name = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getFirstName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setFirstName = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string last_name = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getLastName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setLastName = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string password = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string email = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional bool temporary_password = 8;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getTemporaryPassword = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 8, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setTemporaryPassword = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 8, value);
+};
+
+
+/**
+ * repeated string realm_roles = 9;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getRealmRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 9));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setRealmRolesList = function(value) {
+  return jspb.Message.setField(this, 9, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.addRealmRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 9, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.clearRealmRolesList = function() {
+  return this.setRealmRolesList([]);
+};
+
+
+/**
+ * repeated string client_roles = 10;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getClientRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 10));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setClientRolesList = function(value) {
+  return jspb.Message.setField(this, 10, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.addClientRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 10, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.clearClientRolesList = function() {
+  return this.setClientRolesList([]);
+};
+
+
+/**
+ * repeated UserAttribute attributes = 11;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserAttribute>}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getAttributesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserAttribute>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserAttribute, 11));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserAttribute>} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+*/
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setAttributesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 11, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserAttribute=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.addAttributes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 11, opt_value, proto.org.apache.custos.iam.service.UserAttribute, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.clearAttributesList = function() {
+  return this.setAttributesList([]);
+};
+
+
+/**
+ * optional string state = 12;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getState = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 12, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setState = function(value) {
+  return jspb.Message.setProto3StringField(this, 12, value);
+};
+
+
+/**
+ * optional double creation_time = 13;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getCreationTime = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 13, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setCreationTime = function(value) {
+  return jspb.Message.setProto3FloatField(this, 13, value);
+};
+
+
+/**
+ * optional double last_login_at = 14;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.getLastLoginAt = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 14, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.UserRepresentation.prototype.setLastLoginAt = function(value) {
+  return jspb.Message.setProto3FloatField(this, 14, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.repeatedFields_ = [3,4,5,6,7];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.GroupRepresentation.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.GroupRepresentation} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    id: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    realmRolesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    clientRolesList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f,
+    attributesList: jspb.Message.toObjectList(msg.getAttributesList(),
+    proto.org.apache.custos.iam.service.UserAttribute.toObject, includeInstance),
+    usersList: jspb.Message.toObjectList(msg.getUsersList(),
+    proto.org.apache.custos.iam.service.UserRepresentation.toObject, includeInstance),
+    subGroupsList: jspb.Message.toObjectList(msg.getSubGroupsList(),
+    proto.org.apache.custos.iam.service.GroupRepresentation.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.GroupRepresentation;
+  return proto.org.apache.custos.iam.service.GroupRepresentation.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.GroupRepresentation} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRealmRoles(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addClientRoles(value);
+      break;
+    case 5:
+      var value = new proto.org.apache.custos.iam.service.UserAttribute;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserAttribute.deserializeBinaryFromReader);
+      msg.addAttributes(value);
+      break;
+    case 6:
+      var value = new proto.org.apache.custos.iam.service.UserRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinaryFromReader);
+      msg.addUsers(value);
+      break;
+    case 7:
+      var value = new proto.org.apache.custos.iam.service.GroupRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.GroupRepresentation.deserializeBinaryFromReader);
+      msg.addSubGroups(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.GroupRepresentation.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.GroupRepresentation} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getRealmRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getClientRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      4,
+      f
+    );
+  }
+  f = message.getAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      5,
+      f,
+      proto.org.apache.custos.iam.service.UserAttribute.serializeBinaryToWriter
+    );
+  }
+  f = message.getUsersList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      6,
+      f,
+      proto.org.apache.custos.iam.service.UserRepresentation.serializeBinaryToWriter
+    );
+  }
+  f = message.getSubGroupsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      7,
+      f,
+      proto.org.apache.custos.iam.service.GroupRepresentation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string id = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string realm_roles = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.getRealmRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.setRealmRolesList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.addRealmRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.clearRealmRolesList = function() {
+  return this.setRealmRolesList([]);
+};
+
+
+/**
+ * repeated string client_roles = 4;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.getClientRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 4));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.setClientRolesList = function(value) {
+  return jspb.Message.setField(this, 4, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.addClientRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.clearClientRolesList = function() {
+  return this.setClientRolesList([]);
+};
+
+
+/**
+ * repeated UserAttribute attributes = 5;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserAttribute>}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.getAttributesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserAttribute>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserAttribute, 5));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserAttribute>} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+*/
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.setAttributesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 5, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserAttribute=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.addAttributes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.org.apache.custos.iam.service.UserAttribute, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.clearAttributesList = function() {
+  return this.setAttributesList([]);
+};
+
+
+/**
+ * repeated UserRepresentation users = 6;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.getUsersList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserRepresentation, 6));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+*/
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.setUsersList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 6, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.addUsers = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.org.apache.custos.iam.service.UserRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.clearUsersList = function() {
+  return this.setUsersList([]);
+};
+
+
+/**
+ * repeated GroupRepresentation sub_groups = 7;
+ * @return {!Array<!proto.org.apache.custos.iam.service.GroupRepresentation>}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.getSubGroupsList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.GroupRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.GroupRepresentation, 7));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.GroupRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+*/
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.setSubGroupsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 7, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation}
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.addSubGroups = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 7, opt_value, proto.org.apache.custos.iam.service.GroupRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRepresentation.prototype.clearSubGroupsList = function() {
+  return this.setSubGroupsList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.RegisterUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    clientid: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientsec: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    user: (f = msg.getUser()) && proto.org.apache.custos.iam.service.UserRepresentation.toObject(includeInstance, f),
+    performedby: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserRequest}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.RegisterUserRequest;
+  return proto.org.apache.custos.iam.service.RegisterUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserRequest}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsec(value);
+      break;
+    case 5:
+      var value = new proto.org.apache.custos.iam.service.UserRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.RegisterUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientsec();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      5,
+      f,
+      proto.org.apache.custos.iam.service.UserRepresentation.serializeBinaryToWriter
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string accessToken = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string clientId = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string clientSec = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.getClientsec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.setClientsec = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional UserRepresentation user = 5;
+ * @return {?proto.org.apache.custos.iam.service.UserRepresentation}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.getUser = function() {
+  return /** @type{?proto.org.apache.custos.iam.service.UserRepresentation} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.iam.service.UserRepresentation, 5));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.iam.service.UserRepresentation|undefined} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserRequest} returns this
+*/
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 5, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional string performedBy = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUserRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.RegisterUsersRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.RegisterUsersRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    usersList: jspb.Message.toObjectList(msg.getUsersList(),
+    proto.org.apache.custos.iam.service.UserRepresentation.toObject, includeInstance),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientid: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 5, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersRequest}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.RegisterUsersRequest;
+  return proto.org.apache.custos.iam.service.RegisterUsersRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.RegisterUsersRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersRequest}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.UserRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinaryFromReader);
+      msg.addUsers(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.RegisterUsersRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.RegisterUsersRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsersList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.UserRepresentation.serializeBinaryToWriter
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated UserRepresentation users = 1;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.getUsersList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserRepresentation, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersRequest} returns this
+*/
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.setUsersList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.addUsers = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.iam.service.UserRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.clearUsersList = function() {
+  return this.setUsersList([]);
+};
+
+
+/**
+ * optional int64 tenantId = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional string accessToken = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string clientId = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string performedBy = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUsersRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.RegisterUserResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.RegisterUserResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RegisterUserResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    isRegistered: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserResponse}
+ */
+proto.org.apache.custos.iam.service.RegisterUserResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.RegisterUserResponse;
+  return proto.org.apache.custos.iam.service.RegisterUserResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserResponse}
+ */
+proto.org.apache.custos.iam.service.RegisterUserResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsRegistered(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.RegisterUserResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.RegisterUserResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RegisterUserResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getIsRegistered();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool is_registered = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.RegisterUserResponse.prototype.getIsRegistered = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUserResponse} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUserResponse.prototype.setIsRegistered = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.repeatedFields_ = [2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.RegisterUsersResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.RegisterUsersResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    alluseresregistered: jspb.Message.getBooleanFieldWithDefault(msg, 1, false),
+    failedusersList: jspb.Message.toObjectList(msg.getFailedusersList(),
+    proto.org.apache.custos.iam.service.UserRepresentation.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersResponse}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.RegisterUsersResponse;
+  return proto.org.apache.custos.iam.service.RegisterUsersResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.RegisterUsersResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersResponse}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAlluseresregistered(value);
+      break;
+    case 2:
+      var value = new proto.org.apache.custos.iam.service.UserRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinaryFromReader);
+      msg.addFailedusers(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.RegisterUsersResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.RegisterUsersResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAlluseresregistered();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+  f = message.getFailedusersList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.org.apache.custos.iam.service.UserRepresentation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional bool allUseresRegistered = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.prototype.getAlluseresregistered = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersResponse} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.prototype.setAlluseresregistered = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+/**
+ * repeated UserRepresentation failedUsers = 2;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.prototype.getFailedusersList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserRepresentation, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersResponse} returns this
+*/
+proto.org.apache.custos.iam.service.RegisterUsersResponse.prototype.setFailedusersList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation}
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.prototype.addFailedusers = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.org.apache.custos.iam.service.UserRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.RegisterUsersResponse} returns this
+ */
+proto.org.apache.custos.iam.service.RegisterUsersResponse.prototype.clearFailedusersList = function() {
+  return this.setFailedusersList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.UserSearchMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.UserSearchMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    username: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    firstName: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    lastName: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    email: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    id: jspb.Message.getFieldWithDefault(msg, 5, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.UserSearchMetadata}
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.UserSearchMetadata;
+  return proto.org.apache.custos.iam.service.UserSearchMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.UserSearchMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.UserSearchMetadata}
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFirstName(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLastName(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEmail(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.UserSearchMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.UserSearchMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getFirstName();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getLastName();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string username = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string first_name = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.getFirstName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.setFirstName = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string last_name = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.getLastName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.setLastName = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string email = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.getEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.setEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string id = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchMetadata.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.FindUsersRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.FindUsersRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    user: (f = msg.getUser()) && proto.org.apache.custos.iam.service.UserSearchMetadata.toObject(includeInstance, f),
+    offset: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    limit: jspb.Message.getFieldWithDefault(msg, 5, 0),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    clientId: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    clientSec: jspb.Message.getFieldWithDefault(msg, 7, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.FindUsersRequest;
+  return proto.org.apache.custos.iam.service.FindUsersRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.FindUsersRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 3:
+      var value = new proto.org.apache.custos.iam.service.UserSearchMetadata;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserSearchMetadata.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setOffset(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setLimit(value);
+      break;
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSec(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.FindUsersRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.FindUsersRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.org.apache.custos.iam.service.UserSearchMetadata.serializeBinaryToWriter
+    );
+  }
+  f = message.getOffset();
+  if (f !== 0) {
+    writer.writeInt32(
+      4,
+      f
+    );
+  }
+  f = message.getLimit();
+  if (f !== 0) {
+    writer.writeInt32(
+      5,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getClientSec();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional UserSearchMetadata user = 3;
+ * @return {?proto.org.apache.custos.iam.service.UserSearchMetadata}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.getUser = function() {
+  return /** @type{?proto.org.apache.custos.iam.service.UserSearchMetadata} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.iam.service.UserSearchMetadata, 3));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.iam.service.UserSearchMetadata|undefined} value
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest} returns this
+*/
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional int32 offset = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.getOffset = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.setOffset = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional int32 limit = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.getLimit = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.setLimit = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string accessToken = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string client_id = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string client_sec = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.getClientSec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.FindUsersRequest} returns this
+ */
+proto.org.apache.custos.iam.service.FindUsersRequest.prototype.setClientSec = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.UserSearchRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    user: (f = msg.getUser()) && proto.org.apache.custos.iam.service.UserSearchMetadata.toObject(includeInstance, f),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientId: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    clientSec: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.UserSearchRequest}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.UserSearchRequest;
+  return proto.org.apache.custos.iam.service.UserSearchRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.UserSearchRequest}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.UserSearchMetadata;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserSearchMetadata.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSec(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.UserSearchRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.UserSearchMetadata.serializeBinaryToWriter
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getClientSec();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional UserSearchMetadata user = 1;
+ * @return {?proto.org.apache.custos.iam.service.UserSearchMetadata}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.getUser = function() {
+  return /** @type{?proto.org.apache.custos.iam.service.UserSearchMetadata} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.iam.service.UserSearchMetadata, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.iam.service.UserSearchMetadata|undefined} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchRequest} returns this
+*/
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.iam.service.UserSearchRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional int64 tenantId = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional string accessToken = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string client_id = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string client_sec = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.getClientSec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.setClientSec = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string performedBy = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserSearchRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserSearchRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.FindUsersResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.FindUsersResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    usersList: jspb.Message.toObjectList(msg.getUsersList(),
+    proto.org.apache.custos.iam.service.UserRepresentation.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.FindUsersResponse}
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.FindUsersResponse;
+  return proto.org.apache.custos.iam.service.FindUsersResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.FindUsersResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.FindUsersResponse}
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.UserRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinaryFromReader);
+      msg.addUsers(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.FindUsersResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.FindUsersResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsersList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.UserRepresentation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated UserRepresentation users = 1;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.prototype.getUsersList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserRepresentation, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.FindUsersResponse} returns this
+*/
+proto.org.apache.custos.iam.service.FindUsersResponse.prototype.setUsersList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation}
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.prototype.addUsers = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.iam.service.UserRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.FindUsersResponse} returns this
+ */
+proto.org.apache.custos.iam.service.FindUsersResponse.prototype.clearUsersList = function() {
+  return this.setUsersList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.ResetUserPassword.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.ResetUserPassword} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    username: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    password: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    clientid: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    clientsec: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.ResetUserPassword}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.ResetUserPassword;
+  return proto.org.apache.custos.iam.service.ResetUserPassword.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.ResetUserPassword} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.ResetUserPassword}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsec(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.ResetUserPassword.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.ResetUserPassword} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getClientsec();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string username = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ResetUserPassword} returns this
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string password = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ResetUserPassword} returns this
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenantId = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.ResetUserPassword} returns this
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string accessToken = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ResetUserPassword} returns this
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string clientId = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ResetUserPassword} returns this
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string clientSec = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.getClientsec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.ResetUserPassword} returns this
+ */
+proto.org.apache.custos.iam.service.ResetUserPassword.prototype.setClientsec = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.repeatedFields_ = [3,4];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.DeleteUserRolesRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    username: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    clientRolesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    rolesList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f,
+    accessToken: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    clientId: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    performedBy: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    id: jspb.Message.getFieldWithDefault(msg, 8, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.DeleteUserRolesRequest;
+  return proto.org.apache.custos.iam.service.DeleteUserRolesRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addClientRoles(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRoles(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccessToken(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedBy(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.DeleteUserRolesRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getClientRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      4,
+      f
+    );
+  }
+  f = message.getAccessToken();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getPerformedBy();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenant_id = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string username = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string client_roles = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.getClientRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.setClientRolesList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.addClientRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.clearClientRolesList = function() {
+  return this.setClientRolesList([]);
+};
+
+
+/**
+ * repeated string roles = 4;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.getRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 4));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.setRolesList = function(value) {
+  return jspb.Message.setField(this, 4, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.addRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.clearRolesList = function() {
+  return this.setRolesList([]);
+};
+
+
+/**
+ * optional string access_token = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.getAccessToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.setAccessToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string client_id = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string performed_by = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.getPerformedBy = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.setPerformedBy = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string id = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserRolesRequest.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.repeatedFields_ = [2,3,8];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.AddUserRolesRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    usernamesList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f,
+    rolesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    accessToken: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    clientId: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    clientLevel: jspb.Message.getBooleanFieldWithDefault(msg, 6, false),
+    performedBy: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    agentsList: (f = jspb.Message.getRepeatedField(msg, 8)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.AddUserRolesRequest;
+  return proto.org.apache.custos.iam.service.AddUserRolesRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addUsernames(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRoles(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccessToken(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 6:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setClientLevel(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedBy(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addAgents(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.AddUserRolesRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getUsernamesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      2,
+      f
+    );
+  }
+  f = message.getRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getAccessToken();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getClientLevel();
+  if (f) {
+    writer.writeBool(
+      6,
+      f
+    );
+  }
+  f = message.getPerformedBy();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getAgentsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenant_id = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * repeated string usernames = 2;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.getUsernamesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.setUsernamesList = function(value) {
+  return jspb.Message.setField(this, 2, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.addUsernames = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.clearUsernamesList = function() {
+  return this.setUsernamesList([]);
+};
+
+
+/**
+ * repeated string roles = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.getRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.setRolesList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.addRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.clearRolesList = function() {
+  return this.setRolesList([]);
+};
+
+
+/**
+ * optional string access_token = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.getAccessToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.setAccessToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string client_id = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional bool client_level = 6;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.getClientLevel = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.setClientLevel = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 6, value);
+};
+
+
+/**
+ * optional string performed_by = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.getPerformedBy = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.setPerformedBy = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * repeated string agents = 8;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.getAgentsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 8));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.setAgentsList = function(value) {
+  return jspb.Message.setField(this, 8, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.addAgents = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 8, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.AddUserRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserRolesRequest.prototype.clearAgentsList = function() {
+  return this.setAgentsList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.UpdateUserProfileRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.UpdateUserProfileRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    user: (f = msg.getUser()) && proto.org.apache.custos.iam.service.UserRepresentation.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.UpdateUserProfileRequest}
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.UpdateUserProfileRequest;
+  return proto.org.apache.custos.iam.service.UpdateUserProfileRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.UpdateUserProfileRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.UpdateUserProfileRequest}
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 3:
+      var value = new proto.org.apache.custos.iam.service.UserRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.UpdateUserProfileRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.UpdateUserProfileRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.org.apache.custos.iam.service.UserRepresentation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string accessToken = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UpdateUserProfileRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenantId = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.UpdateUserProfileRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional UserRepresentation user = 3;
+ * @return {?proto.org.apache.custos.iam.service.UserRepresentation}
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.getUser = function() {
+  return /** @type{?proto.org.apache.custos.iam.service.UserRepresentation} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.iam.service.UserRepresentation, 3));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.iam.service.UserRepresentation|undefined} value
+ * @return {!proto.org.apache.custos.iam.service.UpdateUserProfileRequest} returns this
+*/
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.iam.service.UpdateUserProfileRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.UpdateUserProfileRequest.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.AddUserResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.AddUserResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.AddUserResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddUserResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    code: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.AddUserResponse}
+ */
+proto.org.apache.custos.iam.service.AddUserResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.AddUserResponse;
+  return proto.org.apache.custos.iam.service.AddUserResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.AddUserResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.AddUserResponse}
+ */
+proto.org.apache.custos.iam.service.AddUserResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCode(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.AddUserResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.AddUserResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.AddUserResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddUserResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getCode();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string code = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddUserResponse.prototype.getCode = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserResponse} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserResponse.prototype.setCode = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.GetOperationsMetadataRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    traceid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.GetOperationsMetadataRequest}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.GetOperationsMetadataRequest;
+  return proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.GetOperationsMetadataRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.GetOperationsMetadataRequest}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTraceid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.GetOperationsMetadataRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTraceid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 traceId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.prototype.getTraceid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.GetOperationsMetadataRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataRequest.prototype.setTraceid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.OperationMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.OperationMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    event: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    status: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    timestamp: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.OperationMetadata}
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.OperationMetadata;
+  return proto.org.apache.custos.iam.service.OperationMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.OperationMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.OperationMetadata}
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEvent(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setStatus(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTimestamp(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.OperationMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.OperationMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getEvent();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getStatus();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTimestamp();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string event = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.getEvent = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.setEvent = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string status = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.getStatus = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string timeStamp = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.getTimestamp = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.setTimestamp = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string performedBy = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.OperationMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.OperationMetadata.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.GetOperationsMetadataResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadataList: jspb.Message.toObjectList(msg.getMetadataList(),
+    proto.org.apache.custos.iam.service.OperationMetadata.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.GetOperationsMetadataResponse}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.GetOperationsMetadataResponse;
+  return proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.GetOperationsMetadataResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.GetOperationsMetadataResponse}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.OperationMetadata;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.OperationMetadata.deserializeBinaryFromReader);
+      msg.addMetadata(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.GetOperationsMetadataResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadataList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.OperationMetadata.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated OperationMetadata metadata = 1;
+ * @return {!Array<!proto.org.apache.custos.iam.service.OperationMetadata>}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.prototype.getMetadataList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.OperationMetadata>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.OperationMetadata, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.OperationMetadata>} value
+ * @return {!proto.org.apache.custos.iam.service.GetOperationsMetadataResponse} returns this
+*/
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.prototype.setMetadataList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.OperationMetadata=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.OperationMetadata}
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.prototype.addMetadata = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.iam.service.OperationMetadata, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GetOperationsMetadataResponse} returns this
+ */
+proto.org.apache.custos.iam.service.GetOperationsMetadataResponse.prototype.clearMetadataList = function() {
+  return this.setMetadataList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.DeleteTenantRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.DeleteTenantRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.DeleteTenantRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.DeleteTenantRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.DeleteTenantRequest}
+ */
+proto.org.apache.custos.iam.service.DeleteTenantRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.DeleteTenantRequest;
+  return proto.org.apache.custos.iam.service.DeleteTenantRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.DeleteTenantRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.DeleteTenantRequest}
+ */
+proto.org.apache.custos.iam.service.DeleteTenantRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.DeleteTenantRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.DeleteTenantRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.DeleteTenantRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.DeleteTenantRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.DeleteTenantRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteTenantRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteTenantRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.AddRolesRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.AddRolesRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    rolesList: jspb.Message.toObjectList(msg.getRolesList(),
+    proto.org.apache.custos.iam.service.RoleRepresentation.toObject, includeInstance),
+    clientLevel: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    clientId: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.AddRolesRequest}
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.AddRolesRequest;
+  return proto.org.apache.custos.iam.service.AddRolesRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.AddRolesRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.AddRolesRequest}
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.RoleRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.RoleRepresentation.deserializeBinaryFromReader);
+      msg.addRoles(value);
+      break;
+    case 2:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setClientLevel(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.AddRolesRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.AddRolesRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.RoleRepresentation.serializeBinaryToWriter
+    );
+  }
+  f = message.getClientLevel();
+  if (f) {
+    writer.writeBool(
+      2,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated RoleRepresentation roles = 1;
+ * @return {!Array<!proto.org.apache.custos.iam.service.RoleRepresentation>}
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.getRolesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.RoleRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.RoleRepresentation, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.RoleRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.AddRolesRequest} returns this
+*/
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.setRolesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.RoleRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.RoleRepresentation}
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.addRoles = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.iam.service.RoleRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.AddRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.clearRolesList = function() {
+  return this.setRolesList([]);
+};
+
+
+/**
+ * optional bool client_level = 2;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.getClientLevel = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.AddRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.setClientLevel = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.AddRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string client_id = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddRolesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddRolesRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.RoleRepresentation.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.RoleRepresentation} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    description: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    composite: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.RoleRepresentation}
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.RoleRepresentation;
+  return proto.org.apache.custos.iam.service.RoleRepresentation.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.RoleRepresentation} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.RoleRepresentation}
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 3:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setComposite(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.RoleRepresentation.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.RoleRepresentation} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getDescription();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getComposite();
+  if (f) {
+    writer.writeBool(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.RoleRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string description = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.RoleRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.prototype.setDescription = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional bool composite = 3;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.prototype.getComposite = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.RoleRepresentation} returns this
+ */
+proto.org.apache.custos.iam.service.RoleRepresentation.prototype.setComposite = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 3, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.AllRoles.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.AllRoles.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.AllRoles.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.AllRoles} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AllRoles.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    rolesList: jspb.Message.toObjectList(msg.getRolesList(),
+    proto.org.apache.custos.iam.service.RoleRepresentation.toObject, includeInstance),
+    scope: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.AllRoles}
+ */
+proto.org.apache.custos.iam.service.AllRoles.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.AllRoles;
+  return proto.org.apache.custos.iam.service.AllRoles.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.AllRoles} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.AllRoles}
+ */
+proto.org.apache.custos.iam.service.AllRoles.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.RoleRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.RoleRepresentation.deserializeBinaryFromReader);
+      msg.addRoles(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setScope(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.AllRoles.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.AllRoles.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.AllRoles} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AllRoles.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.RoleRepresentation.serializeBinaryToWriter
+    );
+  }
+  f = message.getScope();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated RoleRepresentation roles = 1;
+ * @return {!Array<!proto.org.apache.custos.iam.service.RoleRepresentation>}
+ */
+proto.org.apache.custos.iam.service.AllRoles.prototype.getRolesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.RoleRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.RoleRepresentation, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.RoleRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.AllRoles} returns this
+*/
+proto.org.apache.custos.iam.service.AllRoles.prototype.setRolesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.RoleRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.RoleRepresentation}
+ */
+proto.org.apache.custos.iam.service.AllRoles.prototype.addRoles = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.iam.service.RoleRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.AllRoles} returns this
+ */
+proto.org.apache.custos.iam.service.AllRoles.prototype.clearRolesList = function() {
+  return this.setRolesList([]);
+};
+
+
+/**
+ * optional string scope = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AllRoles.prototype.getScope = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AllRoles} returns this
+ */
+proto.org.apache.custos.iam.service.AllRoles.prototype.setScope = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.AddProtocolMapperRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    attributeName: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    claimName: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    claimType: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 6, 0),
+    clientId: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    mapperType: jspb.Message.getFieldWithDefault(msg, 8, 0),
+    addToIdToken: jspb.Message.getBooleanFieldWithDefault(msg, 9, false),
+    addToAccessToken: jspb.Message.getBooleanFieldWithDefault(msg, 10, false),
+    addToUserInfo: jspb.Message.getBooleanFieldWithDefault(msg, 11, false),
+    multiValued: jspb.Message.getBooleanFieldWithDefault(msg, 12, false),
+    aggregateAttributeValues: jspb.Message.getBooleanFieldWithDefault(msg, 13, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.AddProtocolMapperRequest;
+  return proto.org.apache.custos.iam.service.AddProtocolMapperRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAttributeName(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClaimName(value);
+      break;
+    case 4:
+      var value = /** @type {!proto.org.apache.custos.iam.service.ClaimJSONTypes} */ (reader.readEnum());
+      msg.setClaimType(value);
+      break;
+    case 6:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 8:
+      var value = /** @type {!proto.org.apache.custos.iam.service.MapperTypes} */ (reader.readEnum());
+      msg.setMapperType(value);
+      break;
+    case 9:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAddToIdToken(value);
+      break;
+    case 10:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAddToAccessToken(value);
+      break;
+    case 11:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAddToUserInfo(value);
+      break;
+    case 12:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setMultiValued(value);
+      break;
+    case 13:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAggregateAttributeValues(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.AddProtocolMapperRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getAttributeName();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getClaimName();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClaimType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      4,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      6,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getMapperType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      8,
+      f
+    );
+  }
+  f = message.getAddToIdToken();
+  if (f) {
+    writer.writeBool(
+      9,
+      f
+    );
+  }
+  f = message.getAddToAccessToken();
+  if (f) {
+    writer.writeBool(
+      10,
+      f
+    );
+  }
+  f = message.getAddToUserInfo();
+  if (f) {
+    writer.writeBool(
+      11,
+      f
+    );
+  }
+  f = message.getMultiValued();
+  if (f) {
+    writer.writeBool(
+      12,
+      f
+    );
+  }
+  f = message.getAggregateAttributeValues();
+  if (f) {
+    writer.writeBool(
+      13,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string attribute_name = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getAttributeName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setAttributeName = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string claim_name = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getClaimName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setClaimName = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional ClaimJSONTypes claim_type = 4;
+ * @return {!proto.org.apache.custos.iam.service.ClaimJSONTypes}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getClaimType = function() {
+  return /** @type {!proto.org.apache.custos.iam.service.ClaimJSONTypes} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.ClaimJSONTypes} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setClaimType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 4, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 6;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 6, value);
+};
+
+
+/**
+ * optional string client_id = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional MapperTypes mapper_type = 8;
+ * @return {!proto.org.apache.custos.iam.service.MapperTypes}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getMapperType = function() {
+  return /** @type {!proto.org.apache.custos.iam.service.MapperTypes} */ (jspb.Message.getFieldWithDefault(this, 8, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.MapperTypes} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setMapperType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 8, value);
+};
+
+
+/**
+ * optional bool add_to_id_token = 9;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getAddToIdToken = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 9, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setAddToIdToken = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 9, value);
+};
+
+
+/**
+ * optional bool add_to_access_token = 10;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getAddToAccessToken = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 10, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setAddToAccessToken = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 10, value);
+};
+
+
+/**
+ * optional bool add_to_user_info = 11;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getAddToUserInfo = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 11, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setAddToUserInfo = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 11, value);
+};
+
+
+/**
+ * optional bool multi_valued = 12;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getMultiValued = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 12, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setMultiValued = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 12, value);
+};
+
+
+/**
+ * optional bool aggregate_attribute_values = 13;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.getAggregateAttributeValues = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 13, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddProtocolMapperRequest.prototype.setAggregateAttributeValues = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 13, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.OperationStatus.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.OperationStatus.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.OperationStatus} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.OperationStatus.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    status: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.OperationStatus}
+ */
+proto.org.apache.custos.iam.service.OperationStatus.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.OperationStatus;
+  return proto.org.apache.custos.iam.service.OperationStatus.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.OperationStatus} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.OperationStatus}
+ */
+proto.org.apache.custos.iam.service.OperationStatus.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setStatus(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.OperationStatus.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.OperationStatus.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.OperationStatus} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.OperationStatus.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getStatus();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool status = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.OperationStatus.prototype.getStatus = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.OperationStatus} returns this
+ */
+proto.org.apache.custos.iam.service.OperationStatus.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.repeatedFields_ = [1,2,7];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.AddUserAttributesRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    attributesList: jspb.Message.toObjectList(msg.getAttributesList(),
+    proto.org.apache.custos.iam.service.UserAttribute.toObject, includeInstance),
+    usersList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f,
+    tenantId: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    clientId: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    accessToken: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    agentsList: (f = jspb.Message.getRepeatedField(msg, 7)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.AddUserAttributesRequest;
+  return proto.org.apache.custos.iam.service.AddUserAttributesRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.UserAttribute;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserAttribute.deserializeBinaryFromReader);
+      msg.addAttributes(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addUsers(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccessToken(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addAgents(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.AddUserAttributesRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.UserAttribute.serializeBinaryToWriter
+    );
+  }
+  f = message.getUsersList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getAccessToken();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getAgentsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated UserAttribute attributes = 1;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserAttribute>}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.getAttributesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserAttribute>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserAttribute, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserAttribute>} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+*/
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.setAttributesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserAttribute=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.addAttributes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.iam.service.UserAttribute, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.clearAttributesList = function() {
+  return this.setAttributesList([]);
+};
+
+
+/**
+ * repeated string users = 2;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.getUsersList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.setUsersList = function(value) {
+  return jspb.Message.setField(this, 2, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.addUsers = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.clearUsersList = function() {
+  return this.setUsersList([]);
+};
+
+
+/**
+ * optional int64 tenant_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string client_id = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string access_token = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.getAccessToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.setAccessToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string performedBy = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * repeated string agents = 7;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.getAgentsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 7));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.setAgentsList = function(value) {
+  return jspb.Message.setField(this, 7, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.addAgents = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 7, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} returns this
+ */
+proto.org.apache.custos.iam.service.AddUserAttributesRequest.prototype.clearAgentsList = function() {
+  return this.setAgentsList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.repeatedFields_ = [1,2,7];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    attributesList: jspb.Message.toObjectList(msg.getAttributesList(),
+    proto.org.apache.custos.iam.service.UserAttribute.toObject, includeInstance),
+    usersList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f,
+    tenantId: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    clientId: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    accessToken: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    agentsList: (f = jspb.Message.getRepeatedField(msg, 7)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.DeleteUserAttributeRequest;
+  return proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.UserAttribute;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserAttribute.deserializeBinaryFromReader);
+      msg.addAttributes(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addUsers(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccessToken(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addAgents(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.UserAttribute.serializeBinaryToWriter
+    );
+  }
+  f = message.getUsersList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getAccessToken();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getAgentsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated UserAttribute attributes = 1;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserAttribute>}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.getAttributesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserAttribute>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserAttribute, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserAttribute>} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+*/
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.setAttributesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserAttribute=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.addAttributes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.iam.service.UserAttribute, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.clearAttributesList = function() {
+  return this.setAttributesList([]);
+};
+
+
+/**
+ * repeated string users = 2;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.getUsersList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.setUsersList = function(value) {
+  return jspb.Message.setField(this, 2, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.addUsers = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.clearUsersList = function() {
+  return this.setUsersList([]);
+};
+
+
+/**
+ * optional int64 tenant_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string client_id = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string access_token = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.getAccessToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.setAccessToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string performedBy = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * repeated string agents = 7;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.getAgentsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 7));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.setAgentsList = function(value) {
+  return jspb.Message.setField(this, 7, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.addAgents = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 7, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} returns this
+ */
+proto.org.apache.custos.iam.service.DeleteUserAttributeRequest.prototype.clearAgentsList = function() {
+  return this.setAgentsList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.UserAttribute.repeatedFields_ = [2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.UserAttribute.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.UserAttribute.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.UserAttribute} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserAttribute.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    key: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    valuesList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute}
+ */
+proto.org.apache.custos.iam.service.UserAttribute.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.UserAttribute;
+  return proto.org.apache.custos.iam.service.UserAttribute.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.UserAttribute} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute}
+ */
+proto.org.apache.custos.iam.service.UserAttribute.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setKey(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addValues(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.UserAttribute.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.UserAttribute.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.UserAttribute} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserAttribute.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKey();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getValuesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string key = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserAttribute.prototype.getKey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute} returns this
+ */
+proto.org.apache.custos.iam.service.UserAttribute.prototype.setKey = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * repeated string values = 2;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.UserAttribute.prototype.getValuesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute} returns this
+ */
+proto.org.apache.custos.iam.service.UserAttribute.prototype.setValuesList = function(value) {
+  return jspb.Message.setField(this, 2, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute} returns this
+ */
+proto.org.apache.custos.iam.service.UserAttribute.prototype.addValues = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute} returns this
+ */
+proto.org.apache.custos.iam.service.UserAttribute.prototype.clearValuesList = function() {
+  return this.setValuesList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.EventPersistenceRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.EventPersistenceRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    adminEvent: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),
+    event: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    enable: jspb.Message.getBooleanFieldWithDefault(msg, 4, false),
+    persistenceTime: jspb.Message.getFieldWithDefault(msg, 5, 0),
+    performedby: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.EventPersistenceRequest}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.EventPersistenceRequest;
+  return proto.org.apache.custos.iam.service.EventPersistenceRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.EventPersistenceRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.EventPersistenceRequest}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAdminEvent(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEvent(value);
+      break;
+    case 4:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setEnable(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setPersistenceTime(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.EventPersistenceRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.EventPersistenceRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAdminEvent();
+  if (f) {
+    writer.writeBool(
+      2,
+      f
+    );
+  }
+  f = message.getEvent();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getEnable();
+  if (f) {
+    writer.writeBool(
+      4,
+      f
+    );
+  }
+  f = message.getPersistenceTime();
+  if (f !== 0) {
+    writer.writeInt64(
+      5,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.EventPersistenceRequest} returns this
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional bool admin_event = 2;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.getAdminEvent = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.EventPersistenceRequest} returns this
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.setAdminEvent = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 2, value);
+};
+
+
+/**
+ * optional string event = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.getEvent = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.EventPersistenceRequest} returns this
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.setEvent = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional bool enable = 4;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.getEnable = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.EventPersistenceRequest} returns this
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.setEnable = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 4, value);
+};
+
+
+/**
+ * optional int64 persistence_time = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.getPersistenceTime = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.EventPersistenceRequest} returns this
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.setPersistenceTime = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+/**
+ * optional string performedBy = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.EventPersistenceRequest} returns this
+ */
+proto.org.apache.custos.iam.service.EventPersistenceRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.repeatedFields_ = [6];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.GroupsRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.GroupsRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientid: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    clientsec: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    groupsList: jspb.Message.toObjectList(msg.getGroupsList(),
+    proto.org.apache.custos.iam.service.GroupRepresentation.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.GroupsRequest}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.GroupsRequest;
+  return proto.org.apache.custos.iam.service.GroupsRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.GroupsRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.GroupsRequest}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsec(value);
+      break;
+    case 6:
+      var value = new proto.org.apache.custos.iam.service.GroupRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.GroupRepresentation.deserializeBinaryFromReader);
+      msg.addGroups(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.GroupsRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.GroupsRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getClientsec();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getGroupsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      6,
+      f,
+      proto.org.apache.custos.iam.service.GroupRepresentation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.GroupsRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string accessToken = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupsRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string performedBy = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupsRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string clientId = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupsRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string clientSec = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.getClientsec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupsRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.setClientsec = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * repeated GroupRepresentation groups = 6;
+ * @return {!Array<!proto.org.apache.custos.iam.service.GroupRepresentation>}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.getGroupsList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.GroupRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.GroupRepresentation, 6));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.GroupRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.GroupsRequest} returns this
+*/
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.setGroupsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 6, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation}
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.addGroups = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.org.apache.custos.iam.service.GroupRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GroupsRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupsRequest.prototype.clearGroupsList = function() {
+  return this.setGroupsList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.GroupRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GroupRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientid: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    clientsec: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    id: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    group: (f = msg.getGroup()) && proto.org.apache.custos.iam.service.GroupRepresentation.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.GroupRequest;
+  return proto.org.apache.custos.iam.service.GroupRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsec(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 7:
+      var value = new proto.org.apache.custos.iam.service.GroupRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.GroupRepresentation.deserializeBinaryFromReader);
+      msg.setGroup(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.GroupRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GroupRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getClientsec();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getGroup();
+  if (f != null) {
+    writer.writeMessage(
+      7,
+      f,
+      proto.org.apache.custos.iam.service.GroupRepresentation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string accessToken = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string performedBy = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string clientId = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string clientSec = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.getClientsec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.setClientsec = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string id = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional GroupRepresentation group = 7;
+ * @return {?proto.org.apache.custos.iam.service.GroupRepresentation}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.getGroup = function() {
+  return /** @type{?proto.org.apache.custos.iam.service.GroupRepresentation} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.iam.service.GroupRepresentation, 7));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.iam.service.GroupRepresentation|undefined} value
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest} returns this
+*/
+proto.org.apache.custos.iam.service.GroupRequest.prototype.setGroup = function(value) {
+  return jspb.Message.setWrapperField(this, 7, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.iam.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.clearGroup = function() {
+  return this.setGroup(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.GroupRequest.prototype.hasGroup = function() {
+  return jspb.Message.getField(this, 7) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.GroupsResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.GroupsResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    groupsList: jspb.Message.toObjectList(msg.getGroupsList(),
+    proto.org.apache.custos.iam.service.GroupRepresentation.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.GroupsResponse}
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.GroupsResponse;
+  return proto.org.apache.custos.iam.service.GroupsResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.GroupsResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.GroupsResponse}
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.GroupRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.GroupRepresentation.deserializeBinaryFromReader);
+      msg.addGroups(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.GroupsResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.GroupsResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getGroupsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.GroupRepresentation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated GroupRepresentation groups = 1;
+ * @return {!Array<!proto.org.apache.custos.iam.service.GroupRepresentation>}
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.prototype.getGroupsList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.GroupRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.GroupRepresentation, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.GroupRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.GroupsResponse} returns this
+*/
+proto.org.apache.custos.iam.service.GroupsResponse.prototype.setGroupsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.GroupRepresentation}
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.prototype.addGroups = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.iam.service.GroupRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GroupsResponse} returns this
+ */
+proto.org.apache.custos.iam.service.GroupsResponse.prototype.clearGroupsList = function() {
+  return this.setGroupsList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.UserGroupMappingRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientid: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    clientsec: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    groupId: jspb.Message.getFieldWithDefault(msg, 7, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.UserGroupMappingRequest}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.UserGroupMappingRequest;
+  return proto.org.apache.custos.iam.service.UserGroupMappingRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.UserGroupMappingRequest}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsec(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGroupId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.UserGroupMappingRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getClientsec();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getGroupId();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string accessToken = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string performedBy = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string clientId = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string clientSec = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.getClientsec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.setClientsec = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string username = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string group_id = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.getGroupId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} returns this
+ */
+proto.org.apache.custos.iam.service.UserGroupMappingRequest.prototype.setGroupId = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.repeatedFields_ = [3];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.AgentClientMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    tenanturl: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    redirecturisList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    clientname: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    accessTokenLifeTime: jspb.Message.getFieldWithDefault(msg, 5, 0),
+    performedby: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    accessToken: jspb.Message.getFieldWithDefault(msg, 7, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.AgentClientMetadata;
+  return proto.org.apache.custos.iam.service.AgentClientMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTenanturl(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRedirecturis(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientname(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setAccessTokenLifeTime(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccessToken(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.AgentClientMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getTenanturl();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getRedirecturisList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getClientname();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getAccessTokenLifeTime();
+  if (f !== 0) {
+    writer.writeInt64(
+      5,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getAccessToken();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string tenantURL = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.getTenanturl = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.setTenanturl = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string redirectURIs = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.getRedirecturisList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.setRedirecturisList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.addRedirecturis = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.clearRedirecturisList = function() {
+  return this.setRedirecturisList([]);
+};
+
+
+/**
+ * optional string clientName = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.getClientname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.setClientname = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional int64 access_token_life_time = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.getAccessTokenLifeTime = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.setAccessTokenLifeTime = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+/**
+ * optional string performedBy = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string access_token = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.getAccessToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.AgentClientMetadata} returns this
+ */
+proto.org.apache.custos.iam.service.AgentClientMetadata.prototype.setAccessToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.Agent.repeatedFields_ = [2,3];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.Agent.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.Agent} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.Agent.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    realmRolesList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f,
+    attributesList: jspb.Message.toObjectList(msg.getAttributesList(),
+    proto.org.apache.custos.iam.service.UserAttribute.toObject, includeInstance),
+    isenabled: jspb.Message.getBooleanFieldWithDefault(msg, 4, false),
+    creationTime: jspb.Message.getFloatingPointFieldWithDefault(msg, 5, 0.0),
+    lastModifiedAt: jspb.Message.getFloatingPointFieldWithDefault(msg, 6, 0.0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.Agent}
+ */
+proto.org.apache.custos.iam.service.Agent.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.Agent;
+  return proto.org.apache.custos.iam.service.Agent.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.Agent} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.Agent}
+ */
+proto.org.apache.custos.iam.service.Agent.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRealmRoles(value);
+      break;
+    case 3:
+      var value = new proto.org.apache.custos.iam.service.UserAttribute;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserAttribute.deserializeBinaryFromReader);
+      msg.addAttributes(value);
+      break;
+    case 4:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsenabled(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setCreationTime(value);
+      break;
+    case 6:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setLastModifiedAt(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.Agent.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.Agent} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.Agent.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getRealmRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      2,
+      f
+    );
+  }
+  f = message.getAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      3,
+      f,
+      proto.org.apache.custos.iam.service.UserAttribute.serializeBinaryToWriter
+    );
+  }
+  f = message.getIsenabled();
+  if (f) {
+    writer.writeBool(
+      4,
+      f
+    );
+  }
+  f = message.getCreationTime();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      5,
+      f
+    );
+  }
+  f = message.getLastModifiedAt();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.Agent} returns this
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * repeated string realm_roles = 2;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.getRealmRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.iam.service.Agent} returns this
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.setRealmRolesList = function(value) {
+  return jspb.Message.setField(this, 2, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.Agent} returns this
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.addRealmRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.Agent} returns this
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.clearRealmRolesList = function() {
+  return this.setRealmRolesList([]);
+};
+
+
+/**
+ * repeated UserAttribute attributes = 3;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserAttribute>}
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.getAttributesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserAttribute>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserAttribute, 3));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserAttribute>} value
+ * @return {!proto.org.apache.custos.iam.service.Agent} returns this
+*/
+proto.org.apache.custos.iam.service.Agent.prototype.setAttributesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 3, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserAttribute=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserAttribute}
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.addAttributes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.org.apache.custos.iam.service.UserAttribute, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.Agent} returns this
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.clearAttributesList = function() {
+  return this.setAttributesList([]);
+};
+
+
+/**
+ * optional bool isEnabled = 4;
+ * @return {boolean}
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.getIsenabled = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.iam.service.Agent} returns this
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.setIsenabled = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 4, value);
+};
+
+
+/**
+ * optional double creation_time = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.getCreationTime = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 5, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.Agent} returns this
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.setCreationTime = function(value) {
+  return jspb.Message.setProto3FloatField(this, 5, value);
+};
+
+
+/**
+ * optional double last_modified_at = 6;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.getLastModifiedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 6, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.Agent} returns this
+ */
+proto.org.apache.custos.iam.service.Agent.prototype.setLastModifiedAt = function(value) {
+  return jspb.Message.setProto3FloatField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.GetAllResources.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.GetAllResources.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.GetAllResources} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GetAllResources.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    clientid: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    resourceType: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.GetAllResources}
+ */
+proto.org.apache.custos.iam.service.GetAllResources.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.GetAllResources;
+  return proto.org.apache.custos.iam.service.GetAllResources.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.GetAllResources} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.GetAllResources}
+ */
+proto.org.apache.custos.iam.service.GetAllResources.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 3:
+      var value = /** @type {!proto.org.apache.custos.iam.service.ResourceTypes} */ (reader.readEnum());
+      msg.setResourceType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.GetAllResources.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.GetAllResources.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.GetAllResources} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GetAllResources.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getResourceType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.iam.service.GetAllResources.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.iam.service.GetAllResources} returns this
+ */
+proto.org.apache.custos.iam.service.GetAllResources.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string clientId = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.iam.service.GetAllResources.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.iam.service.GetAllResources} returns this
+ */
+proto.org.apache.custos.iam.service.GetAllResources.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional ResourceTypes resource_type = 3;
+ * @return {!proto.org.apache.custos.iam.service.ResourceTypes}
+ */
+proto.org.apache.custos.iam.service.GetAllResources.prototype.getResourceType = function() {
+  return /** @type {!proto.org.apache.custos.iam.service.ResourceTypes} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.ResourceTypes} value
+ * @return {!proto.org.apache.custos.iam.service.GetAllResources} returns this
+ */
+proto.org.apache.custos.iam.service.GetAllResources.prototype.setResourceType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 3, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.repeatedFields_ = [1,2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.iam.service.GetAllResourcesResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.iam.service.GetAllResourcesResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    agentsList: jspb.Message.toObjectList(msg.getAgentsList(),
+    proto.org.apache.custos.iam.service.Agent.toObject, includeInstance),
+    usersList: jspb.Message.toObjectList(msg.getUsersList(),
+    proto.org.apache.custos.iam.service.UserRepresentation.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.iam.service.GetAllResourcesResponse}
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.iam.service.GetAllResourcesResponse;
+  return proto.org.apache.custos.iam.service.GetAllResourcesResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.iam.service.GetAllResourcesResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.iam.service.GetAllResourcesResponse}
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.iam.service.Agent;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.Agent.deserializeBinaryFromReader);
+      msg.addAgents(value);
+      break;
+    case 2:
+      var value = new proto.org.apache.custos.iam.service.UserRepresentation;
+      reader.readMessage(value,proto.org.apache.custos.iam.service.UserRepresentation.deserializeBinaryFromReader);
+      msg.addUsers(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.iam.service.GetAllResourcesResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.iam.service.GetAllResourcesResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAgentsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.iam.service.Agent.serializeBinaryToWriter
+    );
+  }
+  f = message.getUsersList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.org.apache.custos.iam.service.UserRepresentation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Agent agents = 1;
+ * @return {!Array<!proto.org.apache.custos.iam.service.Agent>}
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.getAgentsList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.Agent>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.Agent, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.Agent>} value
+ * @return {!proto.org.apache.custos.iam.service.GetAllResourcesResponse} returns this
+*/
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.setAgentsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.Agent=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.Agent}
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.addAgents = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.iam.service.Agent, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GetAllResourcesResponse} returns this
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.clearAgentsList = function() {
+  return this.setAgentsList([]);
+};
+
+
+/**
+ * repeated UserRepresentation users = 2;
+ * @return {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.getUsersList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.iam.service.UserRepresentation, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.iam.service.UserRepresentation>} value
+ * @return {!proto.org.apache.custos.iam.service.GetAllResourcesResponse} returns this
+*/
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.setUsersList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserRepresentation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.iam.service.UserRepresentation}
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.addUsers = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.org.apache.custos.iam.service.UserRepresentation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.iam.service.GetAllResourcesResponse} returns this
+ */
+proto.org.apache.custos.iam.service.GetAllResourcesResponse.prototype.clearUsersList = function() {
+  return this.setUsersList([]);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.iam.service.FederatedIDPs = {
+  CILOGON: 0,
+  FACEBOOK: 1,
+  GOOGLE: 2,
+  LINKEDIN: 3,
+  TWITTER: 4,
+  CUSTOM_OIDC: 5
+};
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.iam.service.MapperTypes = {
+  USER_ATTRIBUTE: 0,
+  USER_REALM_ROLE: 1,
+  USER_CLIENT_ROLE: 2
+};
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.iam.service.ClaimJSONTypes = {
+  STRING: 0,
+  LONG: 1,
+  INTEGER: 2,
+  BOOLEAN: 3,
+  JSON: 4
+};
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.iam.service.ResourceTypes = {
+  USER: 0,
+  AGENT: 1
+};
+
+goog.object.extend(exports, proto.org.apache.custos.iam.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/identity-service/IdentityService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/identity-service/IdentityService_pb.js
new file mode 100644
index 0000000..6a93898
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/identity-service/IdentityService_pb.js
@@ -0,0 +1,3255 @@
+// source: src/main/proto/IdentityService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+var google_protobuf_struct_pb = require('google-protobuf/google/protobuf/struct_pb.js');
+goog.object.extend(proto, google_protobuf_struct_pb);
+goog.exportSymbol('proto.org.apache.custos.identity.service.AuthToken', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.AuthenticationRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.AuthorizationResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.Claim', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.EndSessionRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetJWKSRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetOIDCConfiguration', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetTokenRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.IsAuthenticateResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.OperationStatus', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.TokenResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.User', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.AuthToken = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.identity.service.AuthToken.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.AuthToken, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.AuthToken.displayName = 'proto.org.apache.custos.identity.service.AuthToken';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.Claim = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.Claim, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.Claim.displayName = 'proto.org.apache.custos.identity.service.Claim';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.User = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.User, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.User.displayName = 'proto.org.apache.custos.identity.service.User';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetTokenRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetTokenRequest.displayName = 'proto.org.apache.custos.identity.service.GetTokenRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.TokenResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.TokenResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.TokenResponse.displayName = 'proto.org.apache.custos.identity.service.TokenResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.AuthenticationRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.AuthenticationRequest.displayName = 'proto.org.apache.custos.identity.service.AuthenticationRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.IsAuthenticateResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.IsAuthenticateResponse.displayName = 'proto.org.apache.custos.identity.service.IsAuthenticateResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.displayName = 'proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.displayName = 'proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.AuthorizationResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.AuthorizationResponse.displayName = 'proto.org.apache.custos.identity.service.AuthorizationResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetOIDCConfiguration, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetOIDCConfiguration.displayName = 'proto.org.apache.custos.identity.service.GetOIDCConfiguration';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetJWKSRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetJWKSRequest.displayName = 'proto.org.apache.custos.identity.service.GetJWKSRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.EndSessionRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.EndSessionRequest.displayName = 'proto.org.apache.custos.identity.service.EndSessionRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.OperationStatus = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.OperationStatus, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.OperationStatus.displayName = 'proto.org.apache.custos.identity.service.OperationStatus';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.identity.service.AuthToken.repeatedFields_ = [2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.AuthToken.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthToken.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    claimsList: jspb.Message.toObjectList(msg.getClaimsList(),
+    proto.org.apache.custos.identity.service.Claim.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.AuthToken}
+ */
+proto.org.apache.custos.identity.service.AuthToken.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.AuthToken;
+  return proto.org.apache.custos.identity.service.AuthToken.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.AuthToken}
+ */
+proto.org.apache.custos.identity.service.AuthToken.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 2:
+      var value = new proto.org.apache.custos.identity.service.Claim;
+      reader.readMessage(value,proto.org.apache.custos.identity.service.Claim.deserializeBinaryFromReader);
+      msg.addClaims(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.AuthToken.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthToken.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClaimsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.org.apache.custos.identity.service.Claim.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string accessToken = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthToken} returns this
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * repeated Claim claims = 2;
+ * @return {!Array<!proto.org.apache.custos.identity.service.Claim>}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.getClaimsList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.identity.service.Claim>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.identity.service.Claim, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.identity.service.Claim>} value
+ * @return {!proto.org.apache.custos.identity.service.AuthToken} returns this
+*/
+proto.org.apache.custos.identity.service.AuthToken.prototype.setClaimsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.Claim=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.identity.service.Claim}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.addClaims = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.org.apache.custos.identity.service.Claim, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.identity.service.AuthToken} returns this
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.clearClaimsList = function() {
+  return this.setClaimsList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.Claim.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.Claim} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.Claim.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    key: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    value: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.Claim}
+ */
+proto.org.apache.custos.identity.service.Claim.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.Claim;
+  return proto.org.apache.custos.identity.service.Claim.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.Claim} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.Claim}
+ */
+proto.org.apache.custos.identity.service.Claim.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setKey(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.Claim.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.Claim} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.Claim.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKey();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getValue();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string key = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.getKey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.Claim} returns this
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.setKey = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string value = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.getValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.Claim} returns this
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.setValue = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.User.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.User.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.User} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.User.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    sub: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    fullname: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    firstname: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    lastname: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    emailaddress: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.User}
+ */
+proto.org.apache.custos.identity.service.User.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.User;
+  return proto.org.apache.custos.identity.service.User.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.User} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.User}
+ */
+proto.org.apache.custos.identity.service.User.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSub(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFullname(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFirstname(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLastname(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEmailaddress(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.User.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.User.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.User} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.User.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSub();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getFullname();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getFirstname();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getLastname();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getEmailaddress();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string sub = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getSub = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setSub = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string fullName = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getFullname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setFullname = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string firstName = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getFirstname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setFirstname = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string lastName = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getLastname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setLastname = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string emailAddress = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getEmailaddress = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setEmailaddress = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string username = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetTokenRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    clientId: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    redirectUri: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    code: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    password: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    refreshToken: jspb.Message.getFieldWithDefault(msg, 9, ""),
+    grantType: jspb.Message.getFieldWithDefault(msg, 10, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetTokenRequest;
+  return proto.org.apache.custos.identity.service.GetTokenRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRedirectUri(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCode(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRefreshToken(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGrantType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetTokenRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getRedirectUri();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getCode();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getRefreshToken();
+  if (f.length > 0) {
+    writer.writeString(
+      9,
+      f
+    );
+  }
+  f = message.getGrantType();
+  if (f.length > 0) {
+    writer.writeString(
+      10,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenant_id = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string client_id = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string client_secret = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string redirect_uri = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getRedirectUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setRedirectUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string code = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getCode = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setCode = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string username = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string password = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional string refresh_token = 9;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getRefreshToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setRefreshToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 9, value);
+};
+
+
+/**
+ * optional string grant_type = 10;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getGrantType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 10, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setGrantType = function(value) {
+  return jspb.Message.setProto3StringField(this, 10, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.TokenResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.TokenResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.TokenResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    accessToken: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    expiresIn: jspb.Message.getFloatingPointFieldWithDefault(msg, 2, 0.0),
+    refreshExpiresIn: jspb.Message.getFloatingPointFieldWithDefault(msg, 3, 0.0),
+    refreshToken: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    tokenType: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    idToken: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    notBeforePolicy: jspb.Message.getFloatingPointFieldWithDefault(msg, 7, 0.0),
+    sessionState: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    scope: jspb.Message.getFieldWithDefault(msg, 9, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.TokenResponse;
+  return proto.org.apache.custos.identity.service.TokenResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.TokenResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccessToken(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setExpiresIn(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setRefreshExpiresIn(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRefreshToken(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTokenType(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIdToken(value);
+      break;
+    case 7:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setNotBeforePolicy(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSessionState(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setScope(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.TokenResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.TokenResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.TokenResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAccessToken();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getExpiresIn();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      2,
+      f
+    );
+  }
+  f = message.getRefreshExpiresIn();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      3,
+      f
+    );
+  }
+  f = message.getRefreshToken();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getTokenType();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getIdToken();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getNotBeforePolicy();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      7,
+      f
+    );
+  }
+  f = message.getSessionState();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getScope();
+  if (f.length > 0) {
+    writer.writeString(
+      9,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string access_token = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getAccessToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setAccessToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional double expires_in = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getExpiresIn = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 2, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setExpiresIn = function(value) {
+  return jspb.Message.setProto3FloatField(this, 2, value);
+};
+
+
+/**
+ * optional double refresh_expires_in = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getRefreshExpiresIn = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 3, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setRefreshExpiresIn = function(value) {
+  return jspb.Message.setProto3FloatField(this, 3, value);
+};
+
+
+/**
+ * optional string refresh_token = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getRefreshToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setRefreshToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string token_type = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getTokenType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setTokenType = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string id_token = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getIdToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setIdToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional double not_before_policy = 7;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getNotBeforePolicy = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 7, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setNotBeforePolicy = function(value) {
+  return jspb.Message.setProto3FloatField(this, 7, value);
+};
+
+
+/**
+ * optional string session_state = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getSessionState = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setSessionState = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional string scope = 9;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getScope = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setScope = function(value) {
+  return jspb.Message.setProto3StringField(this, 9, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.AuthenticationRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    username: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    password: jspb.Message.getFieldWithDefault(msg, 5, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.AuthenticationRequest;
+  return proto.org.apache.custos.identity.service.AuthenticationRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.AuthenticationRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string clientId = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string clientSecret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenantId = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string username = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string password = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.IsAuthenticateResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.IsAuthenticateResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    authenticated: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.IsAuthenticateResponse}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.IsAuthenticateResponse;
+  return proto.org.apache.custos.identity.service.IsAuthenticateResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.IsAuthenticateResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.IsAuthenticateResponse}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAuthenticated(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.IsAuthenticateResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.IsAuthenticateResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAuthenticated();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool authenticated = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.prototype.getAuthenticated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.identity.service.IsAuthenticateResponse} returns this
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.prototype.setAuthenticated = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest;
+  return proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string clientId = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string clientSecret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenantId = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest;
+  return proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.AuthorizationResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.AuthorizationResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    authorizationendpoint: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.AuthorizationResponse}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.AuthorizationResponse;
+  return proto.org.apache.custos.identity.service.AuthorizationResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.AuthorizationResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.AuthorizationResponse}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAuthorizationendpoint(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.AuthorizationResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.AuthorizationResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAuthorizationendpoint();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string authorizationEndpoint = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.prototype.getAuthorizationendpoint = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthorizationResponse} returns this
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.prototype.setAuthorizationendpoint = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetOIDCConfiguration.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetOIDCConfiguration;
+  return proto.org.apache.custos.identity.service.GetOIDCConfiguration.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetOIDCConfiguration.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} returns this
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string client_secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} returns this
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} returns this
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetJWKSRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetJWKSRequest;
+  return proto.org.apache.custos.identity.service.GetJWKSRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetJWKSRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string client_secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.EndSessionRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.EndSessionRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    refreshToken: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.EndSessionRequest;
+  return proto.org.apache.custos.identity.service.EndSessionRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.EndSessionRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRefreshToken(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.EndSessionRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.EndSessionRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getRefreshToken();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string client_secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string refresh_token = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.getRefreshToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.setRefreshToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.OperationStatus.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.OperationStatus} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.OperationStatus.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    status: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.OperationStatus}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.OperationStatus;
+  return proto.org.apache.custos.identity.service.OperationStatus.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.OperationStatus} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.OperationStatus}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setStatus(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.OperationStatus.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.OperationStatus} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.OperationStatus.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getStatus();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool status = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.prototype.getStatus = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.identity.service.OperationStatus} returns this
+ */
+proto.org.apache.custos.identity.service.OperationStatus.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+goog.object.extend(exports, proto.org.apache.custos.identity.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/resource-secret-service/ResourceSecretService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/resource-secret-service/ResourceSecretService_pb.js
new file mode 100644
index 0000000..1e785c4
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/resource-secret-service/ResourceSecretService_pb.js
@@ -0,0 +1,2676 @@
+// source: src/main/proto/ResourceSecretService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.CertificateCredential', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.GetSecretRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.PasswordCredential', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.ResourceOwnerType', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.ResourceSecretType', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.ResourceSource', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.ResourceType', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.SSHCredential', null, global);
+goog.exportSymbol('proto.org.apache.custos.resource.secret.service.SecretMetadata', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.SecretMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.SecretMetadata.displayName = 'proto.org.apache.custos.resource.secret.service.SecretMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.GetSecretRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.GetSecretRequest.displayName = 'proto.org.apache.custos.resource.secret.service.GetSecretRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.CertificateCredential, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.CertificateCredential.displayName = 'proto.org.apache.custos.resource.secret.service.CertificateCredential';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.PasswordCredential, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.PasswordCredential.displayName = 'proto.org.apache.custos.resource.secret.service.PasswordCredential';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.SSHCredential, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.SSHCredential.displayName = 'proto.org.apache.custos.resource.secret.service.SSHCredential';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.displayName = 'proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.displayName = 'proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.displayName = 'proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.displayName = 'proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.displayName = 'proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.SecretMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.SecretMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    ownerType: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    resourceType: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    source: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    name: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    value: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    type: jspb.Message.getFieldWithDefault(msg, 6, 0),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 7, 0),
+    ownerId: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    persistedTime: jspb.Message.getFieldWithDefault(msg, 9, 0),
+    token: jspb.Message.getFieldWithDefault(msg, 10, ""),
+    description: jspb.Message.getFieldWithDefault(msg, 11, ""),
+    clientId: jspb.Message.getFieldWithDefault(msg, 12, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.SecretMetadata;
+  return proto.org.apache.custos.resource.secret.service.SecretMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.SecretMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.org.apache.custos.resource.secret.service.ResourceOwnerType} */ (reader.readEnum());
+      msg.setOwnerType(value);
+      break;
+    case 2:
+      var value = /** @type {!proto.org.apache.custos.resource.secret.service.ResourceType} */ (reader.readEnum());
+      msg.setResourceType(value);
+      break;
+    case 3:
+      var value = /** @type {!proto.org.apache.custos.resource.secret.service.ResourceSource} */ (reader.readEnum());
+      msg.setSource(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setValue(value);
+      break;
+    case 6:
+      var value = /** @type {!proto.org.apache.custos.resource.secret.service.ResourceSecretType} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    case 7:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setOwnerId(value);
+      break;
+    case 9:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setPersistedTime(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setToken(value);
+      break;
+    case 11:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 12:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.SecretMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.SecretMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOwnerType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = message.getResourceType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      2,
+      f
+    );
+  }
+  f = message.getSource();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      3,
+      f
+    );
+  }
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getValue();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      6,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      7,
+      f
+    );
+  }
+  f = message.getOwnerId();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getPersistedTime();
+  if (f !== 0) {
+    writer.writeInt64(
+      9,
+      f
+    );
+  }
+  f = message.getToken();
+  if (f.length > 0) {
+    writer.writeString(
+      10,
+      f
+    );
+  }
+  f = message.getDescription();
+  if (f.length > 0) {
+    writer.writeString(
+      11,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      12,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional ResourceOwnerType owner_type = 1;
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceOwnerType}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getOwnerType = function() {
+  return /** @type {!proto.org.apache.custos.resource.secret.service.ResourceOwnerType} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceOwnerType} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setOwnerType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * optional ResourceType resource_type = 2;
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceType}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getResourceType = function() {
+  return /** @type {!proto.org.apache.custos.resource.secret.service.ResourceType} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceType} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setResourceType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 2, value);
+};
+
+
+/**
+ * optional ResourceSource source = 3;
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceSource}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getSource = function() {
+  return /** @type {!proto.org.apache.custos.resource.secret.service.ResourceSource} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceSource} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setSource = function(value) {
+  return jspb.Message.setProto3EnumField(this, 3, value);
+};
+
+
+/**
+ * optional string name = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string value = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setValue = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional ResourceSecretType type = 6;
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceSecretType}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getType = function() {
+  return /** @type {!proto.org.apache.custos.resource.secret.service.ResourceSecretType} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceSecretType} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 6, value);
+};
+
+
+/**
+ * optional int64 tenantId = 7;
+ * @return {number}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 7, value);
+};
+
+
+/**
+ * optional string owner_id = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getOwnerId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setOwnerId = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional int64 persisted_time = 9;
+ * @return {number}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getPersistedTime = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setPersistedTime = function(value) {
+  return jspb.Message.setProto3IntField(this, 9, value);
+};
+
+
+/**
+ * optional string token = 10;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 10, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 10, value);
+};
+
+
+/**
+ * optional string description = 11;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 11, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setDescription = function(value) {
+  return jspb.Message.setProto3StringField(this, 11, value);
+};
+
+
+/**
+ * optional string client_id = 12;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 12, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SecretMetadata.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 12, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.GetSecretRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadata: (f = msg.getMetadata()) && proto.org.apache.custos.resource.secret.service.SecretMetadata.toObject(includeInstance, f),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    clientid: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientsec: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 5, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.GetSecretRequest}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.GetSecretRequest;
+  return proto.org.apache.custos.resource.secret.service.GetSecretRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.GetSecretRequest}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.resource.secret.service.SecretMetadata;
+      reader.readMessage(value,proto.org.apache.custos.resource.secret.service.SecretMetadata.deserializeBinaryFromReader);
+      msg.setMetadata(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsec(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.GetSecretRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadata();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.org.apache.custos.resource.secret.service.SecretMetadata.serializeBinaryToWriter
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientsec();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional SecretMetadata metadata = 1;
+ * @return {?proto.org.apache.custos.resource.secret.service.SecretMetadata}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.getMetadata = function() {
+  return /** @type{?proto.org.apache.custos.resource.secret.service.SecretMetadata} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.resource.secret.service.SecretMetadata, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.resource.secret.service.SecretMetadata|undefined} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} returns this
+*/
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.setMetadata = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.clearMetadata = function() {
+  return this.setMetadata(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.hasMetadata = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional int64 tenantId = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional string clientId = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string clientSec = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.getClientsec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.setClientsec = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string accessToken = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetSecretRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.CertificateCredential.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.CertificateCredential} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadata: (f = msg.getMetadata()) && proto.org.apache.custos.resource.secret.service.SecretMetadata.toObject(includeInstance, f),
+    x509Cert: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    notAfter: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    privateKey: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    lifeTime: jspb.Message.getFieldWithDefault(msg, 6, 0),
+    notBefore: jspb.Message.getFieldWithDefault(msg, 7, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.CertificateCredential}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.CertificateCredential;
+  return proto.org.apache.custos.resource.secret.service.CertificateCredential.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.CertificateCredential} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.CertificateCredential}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.resource.secret.service.SecretMetadata;
+      reader.readMessage(value,proto.org.apache.custos.resource.secret.service.SecretMetadata.deserializeBinaryFromReader);
+      msg.setMetadata(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setX509Cert(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setNotAfter(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPrivateKey(value);
+      break;
+    case 6:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setLifeTime(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setNotBefore(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.CertificateCredential.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.CertificateCredential} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadata();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.org.apache.custos.resource.secret.service.SecretMetadata.serializeBinaryToWriter
+    );
+  }
+  f = message.getX509Cert();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getNotAfter();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getPrivateKey();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getLifeTime();
+  if (f !== 0) {
+    writer.writeInt64(
+      6,
+      f
+    );
+  }
+  f = message.getNotBefore();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional SecretMetadata metadata = 1;
+ * @return {?proto.org.apache.custos.resource.secret.service.SecretMetadata}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.getMetadata = function() {
+  return /** @type{?proto.org.apache.custos.resource.secret.service.SecretMetadata} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.resource.secret.service.SecretMetadata, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.resource.secret.service.SecretMetadata|undefined} value
+ * @return {!proto.org.apache.custos.resource.secret.service.CertificateCredential} returns this
+*/
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.setMetadata = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.resource.secret.service.CertificateCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.clearMetadata = function() {
+  return this.setMetadata(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.hasMetadata = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string x509_cert = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.getX509Cert = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.CertificateCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.setX509Cert = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string not_after = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.getNotAfter = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.CertificateCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.setNotAfter = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string private_key = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.getPrivateKey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.CertificateCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.setPrivateKey = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional int64 life_time = 6;
+ * @return {number}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.getLifeTime = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.resource.secret.service.CertificateCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.setLifeTime = function(value) {
+  return jspb.Message.setProto3IntField(this, 6, value);
+};
+
+
+/**
+ * optional string not_before = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.getNotBefore = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.CertificateCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.CertificateCredential.prototype.setNotBefore = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.PasswordCredential.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.PasswordCredential} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadata: (f = msg.getMetadata()) && proto.org.apache.custos.resource.secret.service.SecretMetadata.toObject(includeInstance, f),
+    password: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.PasswordCredential}
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.PasswordCredential;
+  return proto.org.apache.custos.resource.secret.service.PasswordCredential.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.PasswordCredential} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.PasswordCredential}
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.resource.secret.service.SecretMetadata;
+      reader.readMessage(value,proto.org.apache.custos.resource.secret.service.SecretMetadata.deserializeBinaryFromReader);
+      msg.setMetadata(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.PasswordCredential.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.PasswordCredential} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadata();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.org.apache.custos.resource.secret.service.SecretMetadata.serializeBinaryToWriter
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional SecretMetadata metadata = 1;
+ * @return {?proto.org.apache.custos.resource.secret.service.SecretMetadata}
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.prototype.getMetadata = function() {
+  return /** @type{?proto.org.apache.custos.resource.secret.service.SecretMetadata} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.resource.secret.service.SecretMetadata, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.resource.secret.service.SecretMetadata|undefined} value
+ * @return {!proto.org.apache.custos.resource.secret.service.PasswordCredential} returns this
+*/
+proto.org.apache.custos.resource.secret.service.PasswordCredential.prototype.setMetadata = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.resource.secret.service.PasswordCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.prototype.clearMetadata = function() {
+  return this.setMetadata(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.prototype.hasMetadata = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string password = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.PasswordCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.PasswordCredential.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.SSHCredential.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.SSHCredential} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadata: (f = msg.getMetadata()) && proto.org.apache.custos.resource.secret.service.SecretMetadata.toObject(includeInstance, f),
+    passphrase: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    publicKey: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    privateKey: jspb.Message.getFieldWithDefault(msg, 5, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.SSHCredential}
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.SSHCredential;
+  return proto.org.apache.custos.resource.secret.service.SSHCredential.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.SSHCredential} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.SSHCredential}
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.resource.secret.service.SecretMetadata;
+      reader.readMessage(value,proto.org.apache.custos.resource.secret.service.SecretMetadata.deserializeBinaryFromReader);
+      msg.setMetadata(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassphrase(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPublicKey(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPrivateKey(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.SSHCredential.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.SSHCredential} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadata();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.org.apache.custos.resource.secret.service.SecretMetadata.serializeBinaryToWriter
+    );
+  }
+  f = message.getPassphrase();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getPublicKey();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getPrivateKey();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional SecretMetadata metadata = 1;
+ * @return {?proto.org.apache.custos.resource.secret.service.SecretMetadata}
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.getMetadata = function() {
+  return /** @type{?proto.org.apache.custos.resource.secret.service.SecretMetadata} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.resource.secret.service.SecretMetadata, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.resource.secret.service.SecretMetadata|undefined} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SSHCredential} returns this
+*/
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.setMetadata = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.resource.secret.service.SSHCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.clearMetadata = function() {
+  return this.setMetadata(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.hasMetadata = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string passphrase = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.getPassphrase = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SSHCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.setPassphrase = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string public_key = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.getPublicKey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SSHCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.setPublicKey = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string private_key = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.getPrivateKey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.SSHCredential} returns this
+ */
+proto.org.apache.custos.resource.secret.service.SSHCredential.prototype.setPrivateKey = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    token: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    performedBy: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientId: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest;
+  return proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setToken(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedBy(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getToken();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getPerformedBy();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string token = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.getToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.setToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string performed_by = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.getPerformedBy = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.setPerformedBy = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string client_id = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.repeatedFields_ = [2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    type: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    accessibleTokensList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f,
+    tenantid: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    ownerId: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    allTypes: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),
+    clientId: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest;
+  return proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.org.apache.custos.resource.secret.service.ResourceType} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addAccessibleTokens(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setOwnerId(value);
+      break;
+    case 5:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAllTypes(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = message.getAccessibleTokensList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getOwnerId();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getAllTypes();
+  if (f) {
+    writer.writeBool(
+      5,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional ResourceType type = 1;
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceType}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.getType = function() {
+  return /** @type {!proto.org.apache.custos.resource.secret.service.ResourceType} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceType} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.setType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * repeated string accessible_tokens = 2;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.getAccessibleTokensList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.setAccessibleTokensList = function(value) {
+  return jspb.Message.setField(this, 2, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.addAccessibleTokens = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.clearAccessibleTokensList = function() {
+  return this.setAccessibleTokensList([]);
+};
+
+
+/**
+ * optional int64 tenantId = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string owner_id = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.getOwnerId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.setOwnerId = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional bool all_types = 5;
+ * @return {boolean}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.getAllTypes = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.setAllTypes = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 5, value);
+};
+
+
+/**
+ * optional string client_id = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} returns this
+ */
+proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadataList: jspb.Message.toObjectList(msg.getMetadataList(),
+    proto.org.apache.custos.resource.secret.service.SecretMetadata.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries;
+  return proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.resource.secret.service.SecretMetadata;
+      reader.readMessage(value,proto.org.apache.custos.resource.secret.service.SecretMetadata.deserializeBinaryFromReader);
+      msg.addMetadata(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadataList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.resource.secret.service.SecretMetadata.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated SecretMetadata metadata = 1;
+ * @return {!Array<!proto.org.apache.custos.resource.secret.service.SecretMetadata>}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.prototype.getMetadataList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.resource.secret.service.SecretMetadata>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.resource.secret.service.SecretMetadata, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.resource.secret.service.SecretMetadata>} value
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries} returns this
+*/
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.prototype.setMetadataList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.SecretMetadata=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.resource.secret.service.SecretMetadata}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.prototype.addMetadata = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.resource.secret.service.SecretMetadata, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries} returns this
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries.prototype.clearMetadataList = function() {
+  return this.setMetadataList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    token: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse}
+ */
+proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse;
+  return proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse}
+ */
+proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setToken(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getToken();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string token = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.prototype.getToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse} returns this
+ */
+proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse.prototype.setToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    status: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus;
+  return proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setStatus(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getStatus();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool status = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.prototype.getStatus = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus} returns this
+ */
+proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceOwnerType = {
+  TENANT_USER: 0,
+  CUSTOS: 1,
+  TENANT: 2
+};
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceType = {
+  SERVER_CERTIFICATE: 0,
+  JWT_SIGNING_CERTIFICATE: 1,
+  VAULT_CREDENTIAL: 2
+};
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceSource = {
+  KUBE: 0,
+  LOCAL: 1,
+  EXTERNAL: 2,
+  LETSENCRYPT: 3
+};
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.resource.secret.service.ResourceSecretType = {
+  SSH: 0,
+  PASSWORD: 1,
+  X509_CERTIFICATE: 2
+};
+
+goog.object.extend(exports, proto.org.apache.custos.resource.secret.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/sharing-service/SharingService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/sharing-service/SharingService_pb.js
new file mode 100644
index 0000000..f7e1183
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/sharing-service/SharingService_pb.js
@@ -0,0 +1,3867 @@
+// source: src/main/proto/SharingService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.org.apache.custos.sharing.service.Entities', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.Entity', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.EntityRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.EntitySearchField', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.EntityType', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.EntityTypeRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.EntityTypes', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.PermissionRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.PermissionType', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.PermissionTypeRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.PermissionTypes', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.SearchCondition', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.SearchCriteria', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.SearchRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.SharedOwners', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.SharingRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.sharing.service.Status', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.EntityType = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.EntityType, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.EntityType.displayName = 'proto.org.apache.custos.sharing.service.EntityType';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.PermissionType = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.PermissionType, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.PermissionType.displayName = 'proto.org.apache.custos.sharing.service.PermissionType';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.Entity = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.Entity, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.Entity.displayName = 'proto.org.apache.custos.sharing.service.Entity';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.EntityRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.EntityRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.EntityRequest.displayName = 'proto.org.apache.custos.sharing.service.EntityRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.EntityTypeRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.EntityTypeRequest.displayName = 'proto.org.apache.custos.sharing.service.EntityTypeRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.PermissionTypeRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.PermissionTypeRequest.displayName = 'proto.org.apache.custos.sharing.service.PermissionTypeRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.SearchCriteria, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.SearchCriteria.displayName = 'proto.org.apache.custos.sharing.service.SearchCriteria';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.SearchRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.sharing.service.SearchRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.SearchRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.SearchRequest.displayName = 'proto.org.apache.custos.sharing.service.SearchRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.PermissionRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.PermissionRequest.displayName = 'proto.org.apache.custos.sharing.service.PermissionRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.SharingRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.sharing.service.SharingRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.SharingRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.SharingRequest.displayName = 'proto.org.apache.custos.sharing.service.SharingRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.Status = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.Status, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.Status.displayName = 'proto.org.apache.custos.sharing.service.Status';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.EntityTypes = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.sharing.service.EntityTypes.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.EntityTypes, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.EntityTypes.displayName = 'proto.org.apache.custos.sharing.service.EntityTypes';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.sharing.service.PermissionTypes.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.PermissionTypes, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.PermissionTypes.displayName = 'proto.org.apache.custos.sharing.service.PermissionTypes';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.Entities = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.sharing.service.Entities.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.Entities, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.Entities.displayName = 'proto.org.apache.custos.sharing.service.Entities';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.sharing.service.SharedOwners = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.sharing.service.SharedOwners.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.sharing.service.SharedOwners, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.sharing.service.SharedOwners.displayName = 'proto.org.apache.custos.sharing.service.SharedOwners';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.EntityType.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.EntityType} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.EntityType.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    name: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    description: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    createdAt: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    updatedAt: jspb.Message.getFieldWithDefault(msg, 5, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.EntityType}
+ */
+proto.org.apache.custos.sharing.service.EntityType.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.EntityType;
+  return proto.org.apache.custos.sharing.service.EntityType.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.EntityType} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.EntityType}
+ */
+proto.org.apache.custos.sharing.service.EntityType.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setCreatedAt(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setUpdatedAt(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.EntityType.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.EntityType} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.EntityType.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getDescription();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getCreatedAt();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+  f = message.getUpdatedAt();
+  if (f !== 0) {
+    writer.writeInt64(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityType} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string name = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityType} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string description = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityType} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.setDescription = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional int64 created_at = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.getCreatedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityType} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.setCreatedAt = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional int64 updated_at = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.getUpdatedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityType} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityType.prototype.setUpdatedAt = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.PermissionType.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.PermissionType} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.PermissionType.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    name: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    description: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    createdAt: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    updatedAt: jspb.Message.getFieldWithDefault(msg, 5, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionType}
+ */
+proto.org.apache.custos.sharing.service.PermissionType.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.PermissionType;
+  return proto.org.apache.custos.sharing.service.PermissionType.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.PermissionType} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionType}
+ */
+proto.org.apache.custos.sharing.service.PermissionType.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setCreatedAt(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setUpdatedAt(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.PermissionType.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.PermissionType} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.PermissionType.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getDescription();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getCreatedAt();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+  f = message.getUpdatedAt();
+  if (f !== 0) {
+    writer.writeInt64(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionType} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string name = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionType} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string description = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionType} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.setDescription = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional int64 created_at = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.getCreatedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionType} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.setCreatedAt = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional int64 updated_at = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.getUpdatedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionType} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionType.prototype.setUpdatedAt = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.Entity.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.Entity} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.Entity.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    type: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    ownerId: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    parentId: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    name: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    description: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    binaryData: msg.getBinaryData_asB64(),
+    fullText: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    originalCreationTime: jspb.Message.getFieldWithDefault(msg, 9, 0),
+    createdAt: jspb.Message.getFieldWithDefault(msg, 10, 0),
+    updatedAt: jspb.Message.getFieldWithDefault(msg, 11, 0),
+    sharedCount: jspb.Message.getFieldWithDefault(msg, 12, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.Entity}
+ */
+proto.org.apache.custos.sharing.service.Entity.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.Entity;
+  return proto.org.apache.custos.sharing.service.Entity.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.Entity} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.Entity}
+ */
+proto.org.apache.custos.sharing.service.Entity.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setType(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setOwnerId(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setParentId(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 7:
+      var value = /** @type {!Uint8Array} */ (reader.readBytes());
+      msg.setBinaryData(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFullText(value);
+      break;
+    case 9:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setOriginalCreationTime(value);
+      break;
+    case 10:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setCreatedAt(value);
+      break;
+    case 11:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setUpdatedAt(value);
+      break;
+    case 12:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setSharedCount(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.Entity.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.Entity} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.Entity.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getType();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getOwnerId();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getParentId();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getDescription();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getBinaryData_asU8();
+  if (f.length > 0) {
+    writer.writeBytes(
+      7,
+      f
+    );
+  }
+  f = message.getFullText();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getOriginalCreationTime();
+  if (f !== 0) {
+    writer.writeInt64(
+      9,
+      f
+    );
+  }
+  f = message.getCreatedAt();
+  if (f !== 0) {
+    writer.writeInt64(
+      10,
+      f
+    );
+  }
+  f = message.getUpdatedAt();
+  if (f !== 0) {
+    writer.writeInt64(
+      11,
+      f
+    );
+  }
+  f = message.getSharedCount();
+  if (f !== 0) {
+    writer.writeInt32(
+      12,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string type = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setType = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string owner_id = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getOwnerId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setOwnerId = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string parent_id = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getParentId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setParentId = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string name = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string description = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setDescription = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional bytes binary_data = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getBinaryData = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * optional bytes binary_data = 7;
+ * This is a type-conversion wrapper around `getBinaryData()`
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getBinaryData_asB64 = function() {
+  return /** @type {string} */ (jspb.Message.bytesAsB64(
+      this.getBinaryData()));
+};
+
+
+/**
+ * optional bytes binary_data = 7;
+ * Note that Uint8Array is not supported on all browsers.
+ * @see http://caniuse.com/Uint8Array
+ * This is a type-conversion wrapper around `getBinaryData()`
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getBinaryData_asU8 = function() {
+  return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
+      this.getBinaryData()));
+};
+
+
+/**
+ * @param {!(string|Uint8Array)} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setBinaryData = function(value) {
+  return jspb.Message.setProto3BytesField(this, 7, value);
+};
+
+
+/**
+ * optional string full_text = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getFullText = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setFullText = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional int64 original_creation_time = 9;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getOriginalCreationTime = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setOriginalCreationTime = function(value) {
+  return jspb.Message.setProto3IntField(this, 9, value);
+};
+
+
+/**
+ * optional int64 created_at = 10;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getCreatedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 10, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setCreatedAt = function(value) {
+  return jspb.Message.setProto3IntField(this, 10, value);
+};
+
+
+/**
+ * optional int64 updated_at = 11;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getUpdatedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 11, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setUpdatedAt = function(value) {
+  return jspb.Message.setProto3IntField(this, 11, value);
+};
+
+
+/**
+ * optional int32 shared_count = 12;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.getSharedCount = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 12, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.Entity} returns this
+ */
+proto.org.apache.custos.sharing.service.Entity.prototype.setSharedCount = function(value) {
+  return jspb.Message.setProto3IntField(this, 12, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.EntityRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.EntityRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    entity: (f = msg.getEntity()) && proto.org.apache.custos.sharing.service.Entity.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.EntityRequest}
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.EntityRequest;
+  return proto.org.apache.custos.sharing.service.EntityRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.EntityRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.EntityRequest}
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 3:
+      var value = new proto.org.apache.custos.sharing.service.Entity;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.Entity.deserializeBinaryFromReader);
+      msg.setEntity(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.EntityRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.EntityRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getEntity();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.org.apache.custos.sharing.service.Entity.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional Entity entity = 3;
+ * @return {?proto.org.apache.custos.sharing.service.Entity}
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.getEntity = function() {
+  return /** @type{?proto.org.apache.custos.sharing.service.Entity} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.sharing.service.Entity, 3));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.sharing.service.Entity|undefined} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityRequest} returns this
+*/
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.setEntity = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.sharing.service.EntityRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.clearEntity = function() {
+  return this.setEntity(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.sharing.service.EntityRequest.prototype.hasEntity = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.EntityTypeRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.EntityTypeRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    entityType: (f = msg.getEntityType()) && proto.org.apache.custos.sharing.service.EntityType.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypeRequest}
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.EntityTypeRequest;
+  return proto.org.apache.custos.sharing.service.EntityTypeRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.EntityTypeRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypeRequest}
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 3:
+      var value = new proto.org.apache.custos.sharing.service.EntityType;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.EntityType.deserializeBinaryFromReader);
+      msg.setEntityType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.EntityTypeRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.EntityTypeRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getEntityType();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.org.apache.custos.sharing.service.EntityType.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypeRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypeRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional EntityType entity_type = 3;
+ * @return {?proto.org.apache.custos.sharing.service.EntityType}
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.getEntityType = function() {
+  return /** @type{?proto.org.apache.custos.sharing.service.EntityType} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.sharing.service.EntityType, 3));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.sharing.service.EntityType|undefined} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypeRequest} returns this
+*/
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.setEntityType = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypeRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.clearEntityType = function() {
+  return this.setEntityType(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.sharing.service.EntityTypeRequest.prototype.hasEntityType = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.PermissionTypeRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.PermissionTypeRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    permissionType: (f = msg.getPermissionType()) && proto.org.apache.custos.sharing.service.PermissionType.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypeRequest}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.PermissionTypeRequest;
+  return proto.org.apache.custos.sharing.service.PermissionTypeRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.PermissionTypeRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypeRequest}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 3:
+      var value = new proto.org.apache.custos.sharing.service.PermissionType;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.PermissionType.deserializeBinaryFromReader);
+      msg.setPermissionType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.PermissionTypeRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.PermissionTypeRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getPermissionType();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.org.apache.custos.sharing.service.PermissionType.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypeRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypeRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional PermissionType permission_type = 3;
+ * @return {?proto.org.apache.custos.sharing.service.PermissionType}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.getPermissionType = function() {
+  return /** @type{?proto.org.apache.custos.sharing.service.PermissionType} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.sharing.service.PermissionType, 3));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.sharing.service.PermissionType|undefined} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypeRequest} returns this
+*/
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.setPermissionType = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypeRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.clearPermissionType = function() {
+  return this.setPermissionType(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypeRequest.prototype.hasPermissionType = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.SearchCriteria.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.SearchCriteria} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    searchField: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    value: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    condition: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.SearchCriteria}
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.SearchCriteria;
+  return proto.org.apache.custos.sharing.service.SearchCriteria.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.SearchCriteria} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.SearchCriteria}
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.org.apache.custos.sharing.service.EntitySearchField} */ (reader.readEnum());
+      msg.setSearchField(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setValue(value);
+      break;
+    case 3:
+      var value = /** @type {!proto.org.apache.custos.sharing.service.SearchCondition} */ (reader.readEnum());
+      msg.setCondition(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.SearchCriteria.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.SearchCriteria} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSearchField();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = message.getValue();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getCondition();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional EntitySearchField search_field = 1;
+ * @return {!proto.org.apache.custos.sharing.service.EntitySearchField}
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.prototype.getSearchField = function() {
+  return /** @type {!proto.org.apache.custos.sharing.service.EntitySearchField} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.sharing.service.EntitySearchField} value
+ * @return {!proto.org.apache.custos.sharing.service.SearchCriteria} returns this
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.prototype.setSearchField = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * optional string value = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.prototype.getValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.SearchCriteria} returns this
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.prototype.setValue = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional SearchCondition condition = 3;
+ * @return {!proto.org.apache.custos.sharing.service.SearchCondition}
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.prototype.getCondition = function() {
+  return /** @type {!proto.org.apache.custos.sharing.service.SearchCondition} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.sharing.service.SearchCondition} value
+ * @return {!proto.org.apache.custos.sharing.service.SearchCriteria} returns this
+ */
+proto.org.apache.custos.sharing.service.SearchCriteria.prototype.setCondition = function(value) {
+  return jspb.Message.setProto3EnumField(this, 3, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.repeatedFields_ = [6];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.SearchRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.SearchRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    ownerId: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    offset: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    limit: jspb.Message.getFieldWithDefault(msg, 5, 0),
+    searchCriteriaList: jspb.Message.toObjectList(msg.getSearchCriteriaList(),
+    proto.org.apache.custos.sharing.service.SearchCriteria.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.SearchRequest}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.SearchRequest;
+  return proto.org.apache.custos.sharing.service.SearchRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.SearchRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.SearchRequest}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setOwnerId(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setOffset(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setLimit(value);
+      break;
+    case 6:
+      var value = new proto.org.apache.custos.sharing.service.SearchCriteria;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.SearchCriteria.deserializeBinaryFromReader);
+      msg.addSearchCriteria(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.SearchRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.SearchRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getOwnerId();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getOffset();
+  if (f !== 0) {
+    writer.writeInt32(
+      4,
+      f
+    );
+  }
+  f = message.getLimit();
+  if (f !== 0) {
+    writer.writeInt32(
+      5,
+      f
+    );
+  }
+  f = message.getSearchCriteriaList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      6,
+      f,
+      proto.org.apache.custos.sharing.service.SearchCriteria.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.SearchRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.SearchRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional string owner_id = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.getOwnerId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.SearchRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.setOwnerId = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional int32 offset = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.getOffset = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.SearchRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.setOffset = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional int32 limit = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.getLimit = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.SearchRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.setLimit = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+/**
+ * repeated SearchCriteria search_criteria = 6;
+ * @return {!Array<!proto.org.apache.custos.sharing.service.SearchCriteria>}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.getSearchCriteriaList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.sharing.service.SearchCriteria>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.sharing.service.SearchCriteria, 6));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.sharing.service.SearchCriteria>} value
+ * @return {!proto.org.apache.custos.sharing.service.SearchRequest} returns this
+*/
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.setSearchCriteriaList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 6, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.sharing.service.SearchCriteria=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.sharing.service.SearchCriteria}
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.addSearchCriteria = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.org.apache.custos.sharing.service.SearchCriteria, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.sharing.service.SearchRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SearchRequest.prototype.clearSearchCriteriaList = function() {
+  return this.setSearchCriteriaList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.PermissionRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.PermissionRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    entity: (f = msg.getEntity()) && proto.org.apache.custos.sharing.service.Entity.toObject(includeInstance, f),
+    permissionType: (f = msg.getPermissionType()) && proto.org.apache.custos.sharing.service.PermissionType.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionRequest}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.PermissionRequest;
+  return proto.org.apache.custos.sharing.service.PermissionRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.PermissionRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionRequest}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 3:
+      var value = new proto.org.apache.custos.sharing.service.Entity;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.Entity.deserializeBinaryFromReader);
+      msg.setEntity(value);
+      break;
+    case 4:
+      var value = new proto.org.apache.custos.sharing.service.PermissionType;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.PermissionType.deserializeBinaryFromReader);
+      msg.setPermissionType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.PermissionRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.PermissionRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getEntity();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.org.apache.custos.sharing.service.Entity.serializeBinaryToWriter
+    );
+  }
+  f = message.getPermissionType();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      proto.org.apache.custos.sharing.service.PermissionType.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional Entity entity = 3;
+ * @return {?proto.org.apache.custos.sharing.service.Entity}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.getEntity = function() {
+  return /** @type{?proto.org.apache.custos.sharing.service.Entity} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.sharing.service.Entity, 3));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.sharing.service.Entity|undefined} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionRequest} returns this
+*/
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.setEntity = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.clearEntity = function() {
+  return this.setEntity(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.hasEntity = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional PermissionType permission_type = 4;
+ * @return {?proto.org.apache.custos.sharing.service.PermissionType}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.getPermissionType = function() {
+  return /** @type{?proto.org.apache.custos.sharing.service.PermissionType} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.sharing.service.PermissionType, 4));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.sharing.service.PermissionType|undefined} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionRequest} returns this
+*/
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.setPermissionType = function(value) {
+  return jspb.Message.setWrapperField(this, 4, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.clearPermissionType = function() {
+  return this.setPermissionType(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.sharing.service.PermissionRequest.prototype.hasPermissionType = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.repeatedFields_ = [5];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.SharingRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.SharingRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    entity: (f = msg.getEntity()) && proto.org.apache.custos.sharing.service.Entity.toObject(includeInstance, f),
+    permissionType: (f = msg.getPermissionType()) && proto.org.apache.custos.sharing.service.PermissionType.toObject(includeInstance, f),
+    ownerIdList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
+    cascade: jspb.Message.getBooleanFieldWithDefault(msg, 6, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.SharingRequest;
+  return proto.org.apache.custos.sharing.service.SharingRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.SharingRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 3:
+      var value = new proto.org.apache.custos.sharing.service.Entity;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.Entity.deserializeBinaryFromReader);
+      msg.setEntity(value);
+      break;
+    case 4:
+      var value = new proto.org.apache.custos.sharing.service.PermissionType;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.PermissionType.deserializeBinaryFromReader);
+      msg.setPermissionType(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addOwnerId(value);
+      break;
+    case 6:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setCascade(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.SharingRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.SharingRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getEntity();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.org.apache.custos.sharing.service.Entity.serializeBinaryToWriter
+    );
+  }
+  f = message.getPermissionType();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      proto.org.apache.custos.sharing.service.PermissionType.serializeBinaryToWriter
+    );
+  }
+  f = message.getOwnerIdList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      5,
+      f
+    );
+  }
+  f = message.getCascade();
+  if (f) {
+    writer.writeBool(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional Entity entity = 3;
+ * @return {?proto.org.apache.custos.sharing.service.Entity}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.getEntity = function() {
+  return /** @type{?proto.org.apache.custos.sharing.service.Entity} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.sharing.service.Entity, 3));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.sharing.service.Entity|undefined} value
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+*/
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.setEntity = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.clearEntity = function() {
+  return this.setEntity(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.hasEntity = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional PermissionType permission_type = 4;
+ * @return {?proto.org.apache.custos.sharing.service.PermissionType}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.getPermissionType = function() {
+  return /** @type{?proto.org.apache.custos.sharing.service.PermissionType} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.sharing.service.PermissionType, 4));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.sharing.service.PermissionType|undefined} value
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+*/
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.setPermissionType = function(value) {
+  return jspb.Message.setWrapperField(this, 4, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.clearPermissionType = function() {
+  return this.setPermissionType(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.hasPermissionType = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * repeated string owner_id = 5;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.getOwnerIdList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 5));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.setOwnerIdList = function(value) {
+  return jspb.Message.setField(this, 5, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.addOwnerId = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.clearOwnerIdList = function() {
+  return this.setOwnerIdList([]);
+};
+
+
+/**
+ * optional bool cascade = 6;
+ * @return {boolean}
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.getCascade = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.sharing.service.SharingRequest} returns this
+ */
+proto.org.apache.custos.sharing.service.SharingRequest.prototype.setCascade = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.Status.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.Status.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.Status} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.Status.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    status: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.Status}
+ */
+proto.org.apache.custos.sharing.service.Status.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.Status;
+  return proto.org.apache.custos.sharing.service.Status.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.Status} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.Status}
+ */
+proto.org.apache.custos.sharing.service.Status.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setStatus(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.Status.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.Status.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.Status} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.Status.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getStatus();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool status = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.sharing.service.Status.prototype.getStatus = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.sharing.service.Status} returns this
+ */
+proto.org.apache.custos.sharing.service.Status.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.EntityTypes.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.EntityTypes} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    typesList: jspb.Message.toObjectList(msg.getTypesList(),
+    proto.org.apache.custos.sharing.service.EntityType.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypes}
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.EntityTypes;
+  return proto.org.apache.custos.sharing.service.EntityTypes.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.EntityTypes} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypes}
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.sharing.service.EntityType;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.EntityType.deserializeBinaryFromReader);
+      msg.addTypes(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.EntityTypes.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.EntityTypes} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTypesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.sharing.service.EntityType.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated EntityType types = 1;
+ * @return {!Array<!proto.org.apache.custos.sharing.service.EntityType>}
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.prototype.getTypesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.sharing.service.EntityType>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.sharing.service.EntityType, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.sharing.service.EntityType>} value
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypes} returns this
+*/
+proto.org.apache.custos.sharing.service.EntityTypes.prototype.setTypesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.sharing.service.EntityType=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.sharing.service.EntityType}
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.prototype.addTypes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.sharing.service.EntityType, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.sharing.service.EntityTypes} returns this
+ */
+proto.org.apache.custos.sharing.service.EntityTypes.prototype.clearTypesList = function() {
+  return this.setTypesList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.PermissionTypes.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.PermissionTypes} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    typesList: jspb.Message.toObjectList(msg.getTypesList(),
+    proto.org.apache.custos.sharing.service.PermissionType.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypes}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.PermissionTypes;
+  return proto.org.apache.custos.sharing.service.PermissionTypes.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.PermissionTypes} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypes}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.sharing.service.PermissionType;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.PermissionType.deserializeBinaryFromReader);
+      msg.addTypes(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.PermissionTypes.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.PermissionTypes} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTypesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.sharing.service.PermissionType.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated PermissionType types = 1;
+ * @return {!Array<!proto.org.apache.custos.sharing.service.PermissionType>}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.prototype.getTypesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.sharing.service.PermissionType>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.sharing.service.PermissionType, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.sharing.service.PermissionType>} value
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypes} returns this
+*/
+proto.org.apache.custos.sharing.service.PermissionTypes.prototype.setTypesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.sharing.service.PermissionType=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.sharing.service.PermissionType}
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.prototype.addTypes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.sharing.service.PermissionType, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.sharing.service.PermissionTypes} returns this
+ */
+proto.org.apache.custos.sharing.service.PermissionTypes.prototype.clearTypesList = function() {
+  return this.setTypesList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.sharing.service.Entities.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.Entities.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.Entities.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.Entities} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.Entities.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    entityArrayList: jspb.Message.toObjectList(msg.getEntityArrayList(),
+    proto.org.apache.custos.sharing.service.Entity.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.Entities}
+ */
+proto.org.apache.custos.sharing.service.Entities.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.Entities;
+  return proto.org.apache.custos.sharing.service.Entities.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.Entities} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.Entities}
+ */
+proto.org.apache.custos.sharing.service.Entities.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.sharing.service.Entity;
+      reader.readMessage(value,proto.org.apache.custos.sharing.service.Entity.deserializeBinaryFromReader);
+      msg.addEntityArray(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.Entities.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.Entities.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.Entities} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.Entities.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getEntityArrayList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.sharing.service.Entity.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Entity entity_array = 1;
+ * @return {!Array<!proto.org.apache.custos.sharing.service.Entity>}
+ */
+proto.org.apache.custos.sharing.service.Entities.prototype.getEntityArrayList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.sharing.service.Entity>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.sharing.service.Entity, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.sharing.service.Entity>} value
+ * @return {!proto.org.apache.custos.sharing.service.Entities} returns this
+*/
+proto.org.apache.custos.sharing.service.Entities.prototype.setEntityArrayList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.sharing.service.Entity=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.sharing.service.Entity}
+ */
+proto.org.apache.custos.sharing.service.Entities.prototype.addEntityArray = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.sharing.service.Entity, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.sharing.service.Entities} returns this
+ */
+proto.org.apache.custos.sharing.service.Entities.prototype.clearEntityArrayList = function() {
+  return this.setEntityArrayList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.sharing.service.SharedOwners.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.sharing.service.SharedOwners} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    ownerIdsList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.sharing.service.SharedOwners}
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.sharing.service.SharedOwners;
+  return proto.org.apache.custos.sharing.service.SharedOwners.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.sharing.service.SharedOwners} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.sharing.service.SharedOwners}
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addOwnerIds(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.sharing.service.SharedOwners.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.sharing.service.SharedOwners} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOwnerIdsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated string owner_ids = 1;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.prototype.getOwnerIdsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 1));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.sharing.service.SharedOwners} returns this
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.prototype.setOwnerIdsList = function(value) {
+  return jspb.Message.setField(this, 1, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.sharing.service.SharedOwners} returns this
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.prototype.addOwnerIds = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.sharing.service.SharedOwners} returns this
+ */
+proto.org.apache.custos.sharing.service.SharedOwners.prototype.clearOwnerIdsList = function() {
+  return this.setOwnerIdsList([]);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.sharing.service.SearchCondition = {
+  EQUAL: 0,
+  LIKE: 1,
+  GTE: 2,
+  LTE: 3,
+  NOT: 4
+};
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.sharing.service.EntitySearchField = {
+  NAME: 0,
+  DESCRIPTION: 1,
+  ID: 2,
+  FULL_TEXT: 3,
+  OWNER_ID: 4,
+  CREATED_AT: 5,
+  LAST_MODIFIED_AT: 6,
+  ENTITY_TYPE_ID: 7,
+  PARENT_ID: 8,
+  SHARED_COUNT: 9
+};
+
+goog.object.extend(exports, proto.org.apache.custos.sharing.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/tenant-profile/TenantProfileService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/tenant-profile/TenantProfileService_pb.js
new file mode 100644
index 0000000..ce99acb
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/tenant-profile/TenantProfileService_pb.js
@@ -0,0 +1,4234 @@
+// source: src/main/proto/TenantProfileService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.AddTenantResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.GetTenantRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.GetTenantResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.GetTenantsRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.Tenant', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.TenantStatus', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.tenant.profile.service.Tenant.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.Tenant, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.Tenant.displayName = 'proto.org.apache.custos.tenant.profile.service.Tenant';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.displayName = 'proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.displayName = 'proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.AddTenantResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.AddTenantResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.AddTenantResponse.displayName = 'proto.org.apache.custos.tenant.profile.service.AddTenantResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.displayName = 'proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.GetTenantRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.GetTenantRequest.displayName = 'proto.org.apache.custos.tenant.profile.service.GetTenantRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.GetTenantResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.GetTenantResponse.displayName = 'proto.org.apache.custos.tenant.profile.service.GetTenantResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.displayName = 'proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.displayName = 'proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.displayName = 'proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.displayName = 'proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.displayName = 'proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.displayName = 'proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.displayName = 'proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.displayName = 'proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.displayName = 'proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.displayName = 'proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.profile.service.GetTenantsRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.displayName = 'proto.org.apache.custos.tenant.profile.service.GetTenantsRequest';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.repeatedFields_ = [11,12];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.Tenant.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.Tenant} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    clientName: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    requesterEmail: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    adminFirstName: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    adminLastName: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    adminEmail: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    adminUsername: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    adminPassword: jspb.Message.getFieldWithDefault(msg, 9, ""),
+    tenantStatus: jspb.Message.getFieldWithDefault(msg, 10, 0),
+    contactsList: (f = jspb.Message.getRepeatedField(msg, 11)) == null ? undefined : f,
+    redirectUrisList: (f = jspb.Message.getRepeatedField(msg, 12)) == null ? undefined : f,
+    clientUri: jspb.Message.getFieldWithDefault(msg, 13, ""),
+    scope: jspb.Message.getFieldWithDefault(msg, 14, ""),
+    domain: jspb.Message.getFieldWithDefault(msg, 15, ""),
+    comment: jspb.Message.getFieldWithDefault(msg, 16, ""),
+    logoUri: jspb.Message.getFieldWithDefault(msg, 17, ""),
+    parentTenantId: jspb.Message.getFieldWithDefault(msg, 18, 0),
+    applicationType: jspb.Message.getFieldWithDefault(msg, 19, ""),
+    tokenEndpointAuthMethod: jspb.Message.getFieldWithDefault(msg, 20, ""),
+    jwksUri: jspb.Message.getFieldWithDefault(msg, 21, ""),
+    exampleExtensionParameter: jspb.Message.getFieldWithDefault(msg, 22, ""),
+    tosUri: jspb.Message.getFieldWithDefault(msg, 23, ""),
+    policyUri: jspb.Message.getFieldWithDefault(msg, 24, ""),
+    jwksMap: (f = msg.getJwksMap()) ? f.toObject(includeInstance, undefined) : [],
+    softwareId: jspb.Message.getFieldWithDefault(msg, 26, ""),
+    softwareVersion: jspb.Message.getFieldWithDefault(msg, 27, ""),
+    refeshTokenLifetime: jspb.Message.getFieldWithDefault(msg, 28, 0),
+    clientId: jspb.Message.getFieldWithDefault(msg, 29, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.Tenant;
+  return proto.org.apache.custos.tenant.profile.service.Tenant.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.Tenant} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientName(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRequesterEmail(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminFirstName(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminLastName(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminEmail(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminUsername(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminPassword(value);
+      break;
+    case 10:
+      var value = /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (reader.readEnum());
+      msg.setTenantStatus(value);
+      break;
+    case 11:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addContacts(value);
+      break;
+    case 12:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRedirectUris(value);
+      break;
+    case 13:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientUri(value);
+      break;
+    case 14:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setScope(value);
+      break;
+    case 15:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDomain(value);
+      break;
+    case 16:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setComment(value);
+      break;
+    case 17:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLogoUri(value);
+      break;
+    case 18:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setParentTenantId(value);
+      break;
+    case 19:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setApplicationType(value);
+      break;
+    case 20:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTokenEndpointAuthMethod(value);
+      break;
+    case 21:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setJwksUri(value);
+      break;
+    case 22:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setExampleExtensionParameter(value);
+      break;
+    case 23:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTosUri(value);
+      break;
+    case 24:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPolicyUri(value);
+      break;
+    case 25:
+      var value = msg.getJwksMap();
+      reader.readMessage(value, function(message, reader) {
+        jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString, null, "", "");
+         });
+      break;
+    case 26:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSoftwareId(value);
+      break;
+    case 27:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSoftwareVersion(value);
+      break;
+    case 28:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setRefeshTokenLifetime(value);
+      break;
+    case 29:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.Tenant.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.Tenant} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getClientName();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getRequesterEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getAdminFirstName();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getAdminLastName();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getAdminEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getAdminUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getAdminPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      9,
+      f
+    );
+  }
+  f = message.getTenantStatus();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      10,
+      f
+    );
+  }
+  f = message.getContactsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      11,
+      f
+    );
+  }
+  f = message.getRedirectUrisList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      12,
+      f
+    );
+  }
+  f = message.getClientUri();
+  if (f.length > 0) {
+    writer.writeString(
+      13,
+      f
+    );
+  }
+  f = message.getScope();
+  if (f.length > 0) {
+    writer.writeString(
+      14,
+      f
+    );
+  }
+  f = message.getDomain();
+  if (f.length > 0) {
+    writer.writeString(
+      15,
+      f
+    );
+  }
+  f = message.getComment();
+  if (f.length > 0) {
+    writer.writeString(
+      16,
+      f
+    );
+  }
+  f = message.getLogoUri();
+  if (f.length > 0) {
+    writer.writeString(
+      17,
+      f
+    );
+  }
+  f = message.getParentTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      18,
+      f
+    );
+  }
+  f = message.getApplicationType();
+  if (f.length > 0) {
+    writer.writeString(
+      19,
+      f
+    );
+  }
+  f = message.getTokenEndpointAuthMethod();
+  if (f.length > 0) {
+    writer.writeString(
+      20,
+      f
+    );
+  }
+  f = message.getJwksUri();
+  if (f.length > 0) {
+    writer.writeString(
+      21,
+      f
+    );
+  }
+  f = message.getExampleExtensionParameter();
+  if (f.length > 0) {
+    writer.writeString(
+      22,
+      f
+    );
+  }
+  f = message.getTosUri();
+  if (f.length > 0) {
+    writer.writeString(
+      23,
+      f
+    );
+  }
+  f = message.getPolicyUri();
+  if (f.length > 0) {
+    writer.writeString(
+      24,
+      f
+    );
+  }
+  f = message.getJwksMap(true);
+  if (f && f.getLength() > 0) {
+    f.serializeBinary(25, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString);
+  }
+  f = message.getSoftwareId();
+  if (f.length > 0) {
+    writer.writeString(
+      26,
+      f
+    );
+  }
+  f = message.getSoftwareVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      27,
+      f
+    );
+  }
+  f = message.getRefeshTokenLifetime();
+  if (f !== 0) {
+    writer.writeInt64(
+      28,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      29,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenant_id = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string client_name = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getClientName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setClientName = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string requester_email = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getRequesterEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setRequesterEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string admin_first_name = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getAdminFirstName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setAdminFirstName = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string admin_last_name = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getAdminLastName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setAdminLastName = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string admin_email = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getAdminEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setAdminEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string admin_username = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getAdminUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setAdminUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional string admin_password = 9;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getAdminPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setAdminPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 9, value);
+};
+
+
+/**
+ * optional TenantStatus tenant_status = 10;
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatus}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getTenantStatus = function() {
+  return /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (jspb.Message.getFieldWithDefault(this, 10, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantStatus} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setTenantStatus = function(value) {
+  return jspb.Message.setProto3EnumField(this, 10, value);
+};
+
+
+/**
+ * repeated string contacts = 11;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getContactsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 11));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setContactsList = function(value) {
+  return jspb.Message.setField(this, 11, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.addContacts = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 11, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.clearContactsList = function() {
+  return this.setContactsList([]);
+};
+
+
+/**
+ * repeated string redirect_uris = 12;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getRedirectUrisList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 12));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setRedirectUrisList = function(value) {
+  return jspb.Message.setField(this, 12, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.addRedirectUris = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 12, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.clearRedirectUrisList = function() {
+  return this.setRedirectUrisList([]);
+};
+
+
+/**
+ * optional string client_uri = 13;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getClientUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 13, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setClientUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 13, value);
+};
+
+
+/**
+ * optional string scope = 14;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getScope = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 14, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setScope = function(value) {
+  return jspb.Message.setProto3StringField(this, 14, value);
+};
+
+
+/**
+ * optional string domain = 15;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getDomain = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 15, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setDomain = function(value) {
+  return jspb.Message.setProto3StringField(this, 15, value);
+};
+
+
+/**
+ * optional string comment = 16;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getComment = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 16, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setComment = function(value) {
+  return jspb.Message.setProto3StringField(this, 16, value);
+};
+
+
+/**
+ * optional string logo_uri = 17;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getLogoUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 17, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setLogoUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 17, value);
+};
+
+
+/**
+ * optional int64 parent_tenant_id = 18;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getParentTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 18, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setParentTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 18, value);
+};
+
+
+/**
+ * optional string application_type = 19;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getApplicationType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 19, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setApplicationType = function(value) {
+  return jspb.Message.setProto3StringField(this, 19, value);
+};
+
+
+/**
+ * optional string token_endpoint_auth_method = 20;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getTokenEndpointAuthMethod = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 20, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setTokenEndpointAuthMethod = function(value) {
+  return jspb.Message.setProto3StringField(this, 20, value);
+};
+
+
+/**
+ * optional string jwks_uri = 21;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getJwksUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 21, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setJwksUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 21, value);
+};
+
+
+/**
+ * optional string example_extension_parameter = 22;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getExampleExtensionParameter = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 22, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setExampleExtensionParameter = function(value) {
+  return jspb.Message.setProto3StringField(this, 22, value);
+};
+
+
+/**
+ * optional string tos_uri = 23;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getTosUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 23, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setTosUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 23, value);
+};
+
+
+/**
+ * optional string policy_uri = 24;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getPolicyUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 24, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setPolicyUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 24, value);
+};
+
+
+/**
+ * map<string, string> jwks = 25;
+ * @param {boolean=} opt_noLazyCreate Do not create the map if
+ * empty, instead returning `undefined`
+ * @return {!jspb.Map<string,string>}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getJwksMap = function(opt_noLazyCreate) {
+  return /** @type {!jspb.Map<string,string>} */ (
+      jspb.Message.getMapField(this, 25, opt_noLazyCreate,
+      null));
+};
+
+
+/**
+ * Clears values from the map. The map will be non-null.
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.clearJwksMap = function() {
+  this.getJwksMap().clear();
+  return this;};
+
+
+/**
+ * optional string software_id = 26;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getSoftwareId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 26, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setSoftwareId = function(value) {
+  return jspb.Message.setProto3StringField(this, 26, value);
+};
+
+
+/**
+ * optional string software_version = 27;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getSoftwareVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 27, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setSoftwareVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 27, value);
+};
+
+
+/**
+ * optional int64 refesh_token_lifetime = 28;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getRefeshTokenLifetime = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 28, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setRefeshTokenLifetime = function(value) {
+  return jspb.Message.setProto3IntField(this, 28, value);
+};
+
+
+/**
+ * optional string client_id = 29;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 29, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.Tenant.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 29, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    updatedattribute: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    updatedattributevalue: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    updatedby: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    updatedat: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata;
+  return proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedattribute(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedattributevalue(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedby(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedat(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUpdatedattribute();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getUpdatedattributevalue();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUpdatedby();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getUpdatedat();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string updatedAttribute = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.getUpdatedattribute = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.setUpdatedattribute = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string updatedAttributeValue = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.getUpdatedattributevalue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.setUpdatedattributevalue = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string updatedBy = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.getUpdatedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.setUpdatedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string updatedAt = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.getUpdatedat = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.prototype.setUpdatedat = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    updatedstatus: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    updatedby: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    updatedat: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata;
+  return proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (reader.readEnum());
+      msg.setUpdatedstatus(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedby(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedat(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUpdatedstatus();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = message.getUpdatedby();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUpdatedat();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional TenantStatus updatedStatus = 1;
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatus}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.prototype.getUpdatedstatus = function() {
+  return /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantStatus} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.prototype.setUpdatedstatus = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * optional string updatedBy = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.prototype.getUpdatedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.prototype.setUpdatedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string updatedAt = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.prototype.getUpdatedat = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.prototype.setUpdatedat = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.AddTenantResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.AddTenantResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.AddTenantResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.AddTenantResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.AddTenantResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.AddTenantResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.AddTenantResponse;
+  return proto.org.apache.custos.tenant.profile.service.AddTenantResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.AddTenantResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.AddTenantResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.AddTenantResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.AddTenantResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.AddTenantResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.AddTenantResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.AddTenantResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.AddTenantResponse.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.AddTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.AddTenantResponse.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenant: (f = msg.getTenant()) && proto.org.apache.custos.tenant.profile.service.Tenant.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse;
+  return proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.tenant.profile.service.Tenant;
+      reader.readMessage(value,proto.org.apache.custos.tenant.profile.service.Tenant.deserializeBinaryFromReader);
+      msg.setTenant(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenant();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.org.apache.custos.tenant.profile.service.Tenant.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional Tenant tenant = 1;
+ * @return {?proto.org.apache.custos.tenant.profile.service.Tenant}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.prototype.getTenant = function() {
+  return /** @type{?proto.org.apache.custos.tenant.profile.service.Tenant} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.tenant.profile.service.Tenant, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.tenant.profile.service.Tenant|undefined} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse} returns this
+*/
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.prototype.setTenant = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.prototype.clearTenant = function() {
+  return this.setTenant(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateTenantResponse.prototype.hasTenant = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.GetTenantRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.GetTenantRequest;
+  return proto.org.apache.custos.tenant.profile.service.GetTenantRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.GetTenantRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.GetTenantResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenant: (f = msg.getTenant()) && proto.org.apache.custos.tenant.profile.service.Tenant.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.GetTenantResponse;
+  return proto.org.apache.custos.tenant.profile.service.GetTenantResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.tenant.profile.service.Tenant;
+      reader.readMessage(value,proto.org.apache.custos.tenant.profile.service.Tenant.deserializeBinaryFromReader);
+      msg.setTenant(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.GetTenantResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenant();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.org.apache.custos.tenant.profile.service.Tenant.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional Tenant tenant = 1;
+ * @return {?proto.org.apache.custos.tenant.profile.service.Tenant}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.prototype.getTenant = function() {
+  return /** @type{?proto.org.apache.custos.tenant.profile.service.Tenant} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.tenant.profile.service.Tenant, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.tenant.profile.service.Tenant|undefined} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantResponse} returns this
+*/
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.prototype.setTenant = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.prototype.clearTenant = function() {
+  return this.setTenant(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantResponse.prototype.hasTenant = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantList: jspb.Message.toObjectList(msg.getTenantList(),
+    proto.org.apache.custos.tenant.profile.service.Tenant.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse;
+  return proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.tenant.profile.service.Tenant;
+      reader.readMessage(value,proto.org.apache.custos.tenant.profile.service.Tenant.deserializeBinaryFromReader);
+      msg.addTenant(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.tenant.profile.service.Tenant.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Tenant tenant = 1;
+ * @return {!Array<!proto.org.apache.custos.tenant.profile.service.Tenant>}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.prototype.getTenantList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.tenant.profile.service.Tenant>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.tenant.profile.service.Tenant, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.tenant.profile.service.Tenant>} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse} returns this
+*/
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.prototype.setTenantList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.Tenant=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.prototype.addTenant = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.tenant.profile.service.Tenant, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse.prototype.clearTenantList = function() {
+  return this.setTenantList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest;
+  return proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    isexist: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse;
+  return proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsexist(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getIsexist();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool isExist = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.prototype.getIsexist = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.IsTenantExistResponse.prototype.setIsexist = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    requesteremail: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest;
+  return proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRequesteremail(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getRequesteremail();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string requesterEmail = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.prototype.getRequesteremail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.prototype.setRequesteremail = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantList: jspb.Message.toObjectList(msg.getTenantList(),
+    proto.org.apache.custos.tenant.profile.service.Tenant.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse;
+  return proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.tenant.profile.service.Tenant;
+      reader.readMessage(value,proto.org.apache.custos.tenant.profile.service.Tenant.deserializeBinaryFromReader);
+      msg.addTenant(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.tenant.profile.service.Tenant.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Tenant tenant = 1;
+ * @return {!Array<!proto.org.apache.custos.tenant.profile.service.Tenant>}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.prototype.getTenantList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.tenant.profile.service.Tenant>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.tenant.profile.service.Tenant, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.tenant.profile.service.Tenant>} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse} returns this
+*/
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.prototype.setTenantList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.Tenant=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.tenant.profile.service.Tenant}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.prototype.addTenant = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.tenant.profile.service.Tenant, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.prototype.clearTenantList = function() {
+  return this.setTenantList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    status: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    updatedby: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    superTenant: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest;
+  return proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (reader.readEnum());
+      msg.setStatus(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedby(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 5:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setSuperTenant(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getStatus();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      2,
+      f
+    );
+  }
+  f = message.getUpdatedby();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+  f = message.getSuperTenant();
+  if (f) {
+    writer.writeBool(
+      5,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional TenantStatus status = 2;
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatus}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.getStatus = function() {
+  return /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantStatus} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3EnumField(this, 2, value);
+};
+
+
+/**
+ * optional string updatedBy = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.getUpdatedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.setUpdatedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional int64 tenantId = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional bool super_tenant = 5;
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.getSuperTenant = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.setSuperTenant = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 5, value);
+};
+
+
+/**
+ * optional string accessToken = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    status: jspb.Message.getFieldWithDefault(msg, 2, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse;
+  return proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (reader.readEnum());
+      msg.setStatus(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getStatus();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional TenantStatus status = 2;
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatus}
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.prototype.getStatus = function() {
+  return /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantStatus} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3EnumField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest;
+  return proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadataList: jspb.Message.toObjectList(msg.getMetadataList(),
+    proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse;
+  return proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata;
+      reader.readMessage(value,proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.deserializeBinaryFromReader);
+      msg.addMetadata(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadataList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated TenantStatusUpdateMetadata metadata = 1;
+ * @return {!Array<!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata>}
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.prototype.getMetadataList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata>} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse} returns this
+*/
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.prototype.setMetadataList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata}
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.prototype.addMetadata = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.prototype.clearMetadataList = function() {
+  return this.setMetadataList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.repeatedFields_ = [2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadataList: jspb.Message.toObjectList(msg.getMetadataList(),
+    proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse;
+  return proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = new proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata;
+      reader.readMessage(value,proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.deserializeBinaryFromReader);
+      msg.addMetadata(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadataList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated TenantAttributeUpdateMetadata metadata = 2;
+ * @return {!Array<!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata>}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.prototype.getMetadataList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata>} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse} returns this
+*/
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.prototype.setMetadataList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata}
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.prototype.addMetadata = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.prototype.clearMetadataList = function() {
+  return this.setMetadataList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    offset: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    limit: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    parentId: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    status: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    requesterEmail: jspb.Message.getFieldWithDefault(msg, 5, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.profile.service.GetTenantsRequest;
+  return proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setOffset(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setLimit(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setParentId(value);
+      break;
+    case 4:
+      var value = /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (reader.readEnum());
+      msg.setStatus(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRequesterEmail(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOffset();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = message.getLimit();
+  if (f !== 0) {
+    writer.writeInt32(
+      2,
+      f
+    );
+  }
+  f = message.getParentId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getStatus();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      4,
+      f
+    );
+  }
+  f = message.getRequesterEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 offset = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.getOffset = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.setOffset = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional int32 limit = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.getLimit = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.setLimit = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional int64 parent_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.getParentId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.setParentId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional TenantStatus status = 4;
+ * @return {!proto.org.apache.custos.tenant.profile.service.TenantStatus}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.getStatus = function() {
+  return /** @type {!proto.org.apache.custos.tenant.profile.service.TenantStatus} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.TenantStatus} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3EnumField(this, 4, value);
+};
+
+
+/**
+ * optional string requester_email = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.getRequesterEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} returns this
+ */
+proto.org.apache.custos.tenant.profile.service.GetTenantsRequest.prototype.setRequesterEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.tenant.profile.service.TenantStatus = {
+  REQUESTED: 0,
+  APPROVED: 1,
+  DENIED: 2,
+  CANCELLED: 3,
+  ACTIVE: 4,
+  DEACTIVATED: 5
+};
+
+goog.object.extend(exports, proto.org.apache.custos.tenant.profile.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/core-services/user-profile/UserProfileService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/core-services/user-profile/UserProfileService_pb.js
new file mode 100644
index 0000000..949e3d4
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/core-services/user-profile/UserProfileService_pb.js
@@ -0,0 +1,3940 @@
+// source: src/main/proto/UserProfileService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.DefaultGroupMembershipTypes', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.GetAllGroupsResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.Group', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.GroupAttribute', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.GroupMembership', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.GroupRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.GroupToGroupMembership', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.Status', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.UserAttribute', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.UserProfile', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.UserProfileRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.UserStatus', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.profile.service.UserTypes', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.UserProfile = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.user.profile.service.UserProfile.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.UserProfile, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.UserProfile.displayName = 'proto.org.apache.custos.user.profile.service.UserProfile';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.UserProfileRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.UserProfileRequest.displayName = 'proto.org.apache.custos.user.profile.service.UserProfileRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.user.profile.service.UserAttribute.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.UserAttribute, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.UserAttribute.displayName = 'proto.org.apache.custos.user.profile.service.UserAttribute';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.displayName = 'proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.displayName = 'proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.displayName = 'proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.displayName = 'proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.displayName = 'proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.GroupRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.GroupRequest.displayName = 'proto.org.apache.custos.user.profile.service.GroupRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.GetAllGroupsResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.displayName = 'proto.org.apache.custos.user.profile.service.GetAllGroupsResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.Group = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.user.profile.service.Group.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.Group, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.Group.displayName = 'proto.org.apache.custos.user.profile.service.Group';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.user.profile.service.GroupAttribute.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.GroupAttribute, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.GroupAttribute.displayName = 'proto.org.apache.custos.user.profile.service.GroupAttribute';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.GroupMembership, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.GroupMembership.displayName = 'proto.org.apache.custos.user.profile.service.GroupMembership';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.GroupToGroupMembership, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.GroupToGroupMembership.displayName = 'proto.org.apache.custos.user.profile.service.GroupToGroupMembership';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.Status = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.Status, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.Status.displayName = 'proto.org.apache.custos.user.profile.service.Status';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.displayName = 'proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.repeatedFields_ = [7,8,9];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.UserProfile.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfile} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    username: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    email: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    firstName: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    lastName: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    createdAt: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    status: jspb.Message.getFieldWithDefault(msg, 6, 0),
+    attributesList: jspb.Message.toObjectList(msg.getAttributesList(),
+    proto.org.apache.custos.user.profile.service.UserAttribute.toObject, includeInstance),
+    clientRolesList: (f = jspb.Message.getRepeatedField(msg, 8)) == null ? undefined : f,
+    realmRolesList: (f = jspb.Message.getRepeatedField(msg, 9)) == null ? undefined : f,
+    lastModifiedAt: jspb.Message.getFieldWithDefault(msg, 10, ""),
+    type: jspb.Message.getFieldWithDefault(msg, 11, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.UserProfile;
+  return proto.org.apache.custos.user.profile.service.UserProfile.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfile} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEmail(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFirstName(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLastName(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCreatedAt(value);
+      break;
+    case 6:
+      var value = /** @type {!proto.org.apache.custos.user.profile.service.UserStatus} */ (reader.readEnum());
+      msg.setStatus(value);
+      break;
+    case 7:
+      var value = new proto.org.apache.custos.user.profile.service.UserAttribute;
+      reader.readMessage(value,proto.org.apache.custos.user.profile.service.UserAttribute.deserializeBinaryFromReader);
+      msg.addAttributes(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addClientRoles(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRealmRoles(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLastModifiedAt(value);
+      break;
+    case 11:
+      var value = /** @type {!proto.org.apache.custos.user.profile.service.UserTypes} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.UserProfile.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfile} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getFirstName();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getLastName();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getCreatedAt();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getStatus();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      6,
+      f
+    );
+  }
+  f = message.getAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      7,
+      f,
+      proto.org.apache.custos.user.profile.service.UserAttribute.serializeBinaryToWriter
+    );
+  }
+  f = message.getClientRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      8,
+      f
+    );
+  }
+  f = message.getRealmRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      9,
+      f
+    );
+  }
+  f = message.getLastModifiedAt();
+  if (f.length > 0) {
+    writer.writeString(
+      10,
+      f
+    );
+  }
+  f = message.getType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      11,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string username = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string email = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string first_name = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getFirstName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setFirstName = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string last_name = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getLastName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setLastName = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string created_at = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getCreatedAt = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setCreatedAt = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional UserStatus status = 6;
+ * @return {!proto.org.apache.custos.user.profile.service.UserStatus}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getStatus = function() {
+  return /** @type {!proto.org.apache.custos.user.profile.service.UserStatus} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.UserStatus} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3EnumField(this, 6, value);
+};
+
+
+/**
+ * repeated UserAttribute attributes = 7;
+ * @return {!Array<!proto.org.apache.custos.user.profile.service.UserAttribute>}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getAttributesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.user.profile.service.UserAttribute>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.user.profile.service.UserAttribute, 7));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.user.profile.service.UserAttribute>} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+*/
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setAttributesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 7, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.UserAttribute=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.UserAttribute}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.addAttributes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 7, opt_value, proto.org.apache.custos.user.profile.service.UserAttribute, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.clearAttributesList = function() {
+  return this.setAttributesList([]);
+};
+
+
+/**
+ * repeated string client_roles = 8;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getClientRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 8));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setClientRolesList = function(value) {
+  return jspb.Message.setField(this, 8, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.addClientRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 8, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.clearClientRolesList = function() {
+  return this.setClientRolesList([]);
+};
+
+
+/**
+ * repeated string realm_roles = 9;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getRealmRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 9));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setRealmRolesList = function(value) {
+  return jspb.Message.setField(this, 9, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.addRealmRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 9, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.clearRealmRolesList = function() {
+  return this.setRealmRolesList([]);
+};
+
+
+/**
+ * optional string last_modified_at = 10;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getLastModifiedAt = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 10, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setLastModifiedAt = function(value) {
+  return jspb.Message.setProto3StringField(this, 10, value);
+};
+
+
+/**
+ * optional UserTypes type = 11;
+ * @return {!proto.org.apache.custos.user.profile.service.UserTypes}
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.getType = function() {
+  return /** @type {!proto.org.apache.custos.user.profile.service.UserTypes} */ (jspb.Message.getFieldWithDefault(this, 11, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.UserTypes} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfile.prototype.setType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 11, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.UserProfileRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    profile: (f = msg.getProfile()) && proto.org.apache.custos.user.profile.service.UserProfile.toObject(includeInstance, f),
+    performedby: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileRequest}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.UserProfileRequest;
+  return proto.org.apache.custos.user.profile.service.UserProfileRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileRequest}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = new proto.org.apache.custos.user.profile.service.UserProfile;
+      reader.readMessage(value,proto.org.apache.custos.user.profile.service.UserProfile.deserializeBinaryFromReader);
+      msg.setProfile(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.UserProfileRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getProfile();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.org.apache.custos.user.profile.service.UserProfile.serializeBinaryToWriter
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional UserProfile profile = 2;
+ * @return {?proto.org.apache.custos.user.profile.service.UserProfile}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.getProfile = function() {
+  return /** @type{?proto.org.apache.custos.user.profile.service.UserProfile} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.user.profile.service.UserProfile, 2));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.user.profile.service.UserProfile|undefined} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileRequest} returns this
+*/
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.setProfile = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.clearProfile = function() {
+  return this.setProfile(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.hasProfile = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string performedBy = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.repeatedFields_ = [3];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.UserAttribute.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.UserAttribute} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    key: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    valueList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.UserAttribute}
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.UserAttribute;
+  return proto.org.apache.custos.user.profile.service.UserAttribute.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.UserAttribute} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.UserAttribute}
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setKey(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.UserAttribute.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.UserAttribute} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getKey();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getValueList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 id = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.getId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.setId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string key = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.getKey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.setKey = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string value = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.getValueList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.setValueList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.UserAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.addValue = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.UserAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserAttribute.prototype.clearValueList = function() {
+  return this.setValueList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    profilesList: jspb.Message.toObjectList(msg.getProfilesList(),
+    proto.org.apache.custos.user.profile.service.UserProfile.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse}
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse;
+  return proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse}
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.user.profile.service.UserProfile;
+      reader.readMessage(value,proto.org.apache.custos.user.profile.service.UserProfile.deserializeBinaryFromReader);
+      msg.addProfiles(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getProfilesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.user.profile.service.UserProfile.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated UserProfile profiles = 1;
+ * @return {!Array<!proto.org.apache.custos.user.profile.service.UserProfile>}
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.prototype.getProfilesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.user.profile.service.UserProfile>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.user.profile.service.UserProfile, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.user.profile.service.UserProfile>} value
+ * @return {!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse} returns this
+*/
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.prototype.setProfilesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfile=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfile}
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.prototype.addProfiles = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.user.profile.service.UserProfile, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse} returns this
+ */
+proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse.prototype.clearProfilesList = function() {
+  return this.setProfilesList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    username: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest;
+  return proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest} returns this
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string username = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest} returns this
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    updatedattribute: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    updatedattributevalue: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    updatedby: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    updatedat: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata;
+  return proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedattribute(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedattributevalue(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedby(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedat(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUpdatedattribute();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getUpdatedattributevalue();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUpdatedby();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getUpdatedat();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string updatedAttribute = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.getUpdatedattribute = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.setUpdatedattribute = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string updatedAttributeValue = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.getUpdatedattributevalue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.setUpdatedattributevalue = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string updatedBy = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.getUpdatedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.setUpdatedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string updatedAt = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.getUpdatedat = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.prototype.setUpdatedat = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    updatedstatus: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    updatedby: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    updatedat: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata;
+  return proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.org.apache.custos.user.profile.service.UserStatus} */ (reader.readEnum());
+      msg.setUpdatedstatus(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedby(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUpdatedat(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUpdatedstatus();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = message.getUpdatedby();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUpdatedat();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional UserStatus updatedStatus = 1;
+ * @return {!proto.org.apache.custos.user.profile.service.UserStatus}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.prototype.getUpdatedstatus = function() {
+  return /** @type {!proto.org.apache.custos.user.profile.service.UserStatus} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.UserStatus} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.prototype.setUpdatedstatus = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * optional string updatedBy = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.prototype.getUpdatedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.prototype.setUpdatedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string updatedAt = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.prototype.getUpdatedat = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.prototype.setUpdatedat = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.repeatedFields_ = [1,2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    attributeauditList: jspb.Message.toObjectList(msg.getAttributeauditList(),
+    proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.toObject, includeInstance),
+    statusauditList: jspb.Message.toObjectList(msg.getStatusauditList(),
+    proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse;
+  return proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata;
+      reader.readMessage(value,proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.deserializeBinaryFromReader);
+      msg.addAttributeaudit(value);
+      break;
+    case 2:
+      var value = new proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata;
+      reader.readMessage(value,proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.deserializeBinaryFromReader);
+      msg.addStatusaudit(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAttributeauditList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.serializeBinaryToWriter
+    );
+  }
+  f = message.getStatusauditList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated UserProfileAttributeUpdateMetadata attributeAudit = 1;
+ * @return {!Array<!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata>}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.getAttributeauditList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata>} value
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse} returns this
+*/
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.setAttributeauditList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.addAttributeaudit = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse} returns this
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.clearAttributeauditList = function() {
+  return this.setAttributeauditList([]);
+};
+
+
+/**
+ * repeated UserProfileStatusUpdateMetadata statusAudit = 2;
+ * @return {!Array<!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata>}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.getStatusauditList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata>} value
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse} returns this
+*/
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.setStatusauditList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata}
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.addStatusaudit = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse} returns this
+ */
+proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.prototype.clearStatusauditList = function() {
+  return this.setStatusauditList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.GroupRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    group: (f = msg.getGroup()) && proto.org.apache.custos.user.profile.service.Group.toObject(includeInstance, f),
+    performedby: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupRequest}
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.GroupRequest;
+  return proto.org.apache.custos.user.profile.service.GroupRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupRequest}
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = new proto.org.apache.custos.user.profile.service.Group;
+      reader.readMessage(value,proto.org.apache.custos.user.profile.service.Group.deserializeBinaryFromReader);
+      msg.setGroup(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.GroupRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getGroup();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.org.apache.custos.user.profile.service.Group.serializeBinaryToWriter
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional Group group = 2;
+ * @return {?proto.org.apache.custos.user.profile.service.Group}
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.getGroup = function() {
+  return /** @type{?proto.org.apache.custos.user.profile.service.Group} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.user.profile.service.Group, 2));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.user.profile.service.Group|undefined} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupRequest} returns this
+*/
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.setGroup = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.clearGroup = function() {
+  return this.setGroup(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.hasGroup = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string performedBy = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupRequest} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    groupsList: jspb.Message.toObjectList(msg.getGroupsList(),
+    proto.org.apache.custos.user.profile.service.Group.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse}
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.GetAllGroupsResponse;
+  return proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse}
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.user.profile.service.Group;
+      reader.readMessage(value,proto.org.apache.custos.user.profile.service.Group.deserializeBinaryFromReader);
+      msg.addGroups(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getGroupsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.org.apache.custos.user.profile.service.Group.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Group groups = 1;
+ * @return {!Array<!proto.org.apache.custos.user.profile.service.Group>}
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.prototype.getGroupsList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.user.profile.service.Group>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.user.profile.service.Group, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.user.profile.service.Group>} value
+ * @return {!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse} returns this
+*/
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.prototype.setGroupsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.Group=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.Group}
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.prototype.addGroups = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.org.apache.custos.user.profile.service.Group, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse} returns this
+ */
+proto.org.apache.custos.user.profile.service.GetAllGroupsResponse.prototype.clearGroupsList = function() {
+  return this.setGroupsList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.user.profile.service.Group.repeatedFields_ = [3,4,8];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.Group.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.Group} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.Group.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    name: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    realmRolesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    clientRolesList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f,
+    parentId: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    createdTime: jspb.Message.getFieldWithDefault(msg, 6, 0),
+    lastModifiedTime: jspb.Message.getFieldWithDefault(msg, 7, 0),
+    attributesList: jspb.Message.toObjectList(msg.getAttributesList(),
+    proto.org.apache.custos.user.profile.service.GroupAttribute.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.Group}
+ */
+proto.org.apache.custos.user.profile.service.Group.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.Group;
+  return proto.org.apache.custos.user.profile.service.Group.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.Group} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.Group}
+ */
+proto.org.apache.custos.user.profile.service.Group.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRealmRoles(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addClientRoles(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setParentId(value);
+      break;
+    case 6:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setCreatedTime(value);
+      break;
+    case 7:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setLastModifiedTime(value);
+      break;
+    case 8:
+      var value = new proto.org.apache.custos.user.profile.service.GroupAttribute;
+      reader.readMessage(value,proto.org.apache.custos.user.profile.service.GroupAttribute.deserializeBinaryFromReader);
+      msg.addAttributes(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.Group.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.Group} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.Group.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getRealmRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getClientRolesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      4,
+      f
+    );
+  }
+  f = message.getParentId();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getCreatedTime();
+  if (f !== 0) {
+    writer.writeInt64(
+      6,
+      f
+    );
+  }
+  f = message.getLastModifiedTime();
+  if (f !== 0) {
+    writer.writeInt64(
+      7,
+      f
+    );
+  }
+  f = message.getAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      8,
+      f,
+      proto.org.apache.custos.user.profile.service.GroupAttribute.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string name = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string realm_roles = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.getRealmRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.setRealmRolesList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.addRealmRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.clearRealmRolesList = function() {
+  return this.setRealmRolesList([]);
+};
+
+
+/**
+ * repeated string client_roles = 4;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.getClientRolesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 4));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.setClientRolesList = function(value) {
+  return jspb.Message.setField(this, 4, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.addClientRoles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.clearClientRolesList = function() {
+  return this.setClientRolesList([]);
+};
+
+
+/**
+ * optional string parent_id = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.getParentId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.setParentId = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional int64 created_time = 6;
+ * @return {number}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.getCreatedTime = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.setCreatedTime = function(value) {
+  return jspb.Message.setProto3IntField(this, 6, value);
+};
+
+
+/**
+ * optional int64 last_modified_time = 7;
+ * @return {number}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.getLastModifiedTime = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.setLastModifiedTime = function(value) {
+  return jspb.Message.setProto3IntField(this, 7, value);
+};
+
+
+/**
+ * repeated GroupAttribute attributes = 8;
+ * @return {!Array<!proto.org.apache.custos.user.profile.service.GroupAttribute>}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.getAttributesList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.user.profile.service.GroupAttribute>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.user.profile.service.GroupAttribute, 8));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.user.profile.service.GroupAttribute>} value
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+*/
+proto.org.apache.custos.user.profile.service.Group.prototype.setAttributesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 8, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupAttribute=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.GroupAttribute}
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.addAttributes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 8, opt_value, proto.org.apache.custos.user.profile.service.GroupAttribute, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.Group} returns this
+ */
+proto.org.apache.custos.user.profile.service.Group.prototype.clearAttributesList = function() {
+  return this.setAttributesList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.repeatedFields_ = [3];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.GroupAttribute.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.GroupAttribute} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    key: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    valueList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupAttribute}
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.GroupAttribute;
+  return proto.org.apache.custos.user.profile.service.GroupAttribute.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.GroupAttribute} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupAttribute}
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setKey(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.GroupAttribute.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.GroupAttribute} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getKey();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getValueList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 id = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.getId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.setId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string key = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.getKey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.setKey = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string value = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.getValueList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.setValueList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.profile.service.GroupAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.addValue = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupAttribute} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupAttribute.prototype.clearValueList = function() {
+  return this.setValueList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.GroupMembership.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    groupId: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    type: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupMembership}
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.GroupMembership;
+  return proto.org.apache.custos.user.profile.service.GroupMembership.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupMembership}
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGroupId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.GroupMembership.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getGroupId();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getType();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupMembership} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string group_id = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.getGroupId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupMembership} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.setGroupId = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string username = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupMembership} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string type = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.getType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupMembership} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupMembership.prototype.setType = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.GroupToGroupMembership.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    parentId: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    childId: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership}
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.GroupToGroupMembership;
+  return proto.org.apache.custos.user.profile.service.GroupToGroupMembership.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership}
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setParentId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setChildId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.GroupToGroupMembership.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getParentId();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getChildId();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string parent_id = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.prototype.getParentId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.prototype.setParentId = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string child_id = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.prototype.getChildId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} returns this
+ */
+proto.org.apache.custos.user.profile.service.GroupToGroupMembership.prototype.setChildId = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.Status.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.Status.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.Status} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.Status.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    status: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.Status}
+ */
+proto.org.apache.custos.user.profile.service.Status.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.Status;
+  return proto.org.apache.custos.user.profile.service.Status.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.Status} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.Status}
+ */
+proto.org.apache.custos.user.profile.service.Status.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setStatus(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.Status.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.Status.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.Status} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.Status.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getStatus();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool status = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.user.profile.service.Status.prototype.getStatus = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.user.profile.service.Status} returns this
+ */
+proto.org.apache.custos.user.profile.service.Status.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    type: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest}
+ */
+proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest;
+  return proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest}
+ */
+proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getType();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string type = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.prototype.getType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest} returns this
+ */
+proto.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.prototype.setType = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.user.profile.service.UserStatus = {
+  ACTIVE: 0,
+  CONFIRMED: 1,
+  APPROVED: 2,
+  DELETED: 3,
+  DUPLICATE: 4,
+  GRACE_PERIOD: 5,
+  INVITED: 6,
+  DENIED: 7,
+  PENDING: 8,
+  PENDING_APPROVAL: 9,
+  PENDING_CONFIRMATION: 10,
+  SUSPENDED: 11,
+  DECLINED: 12,
+  EXPIRED: 13
+};
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.user.profile.service.DefaultGroupMembershipTypes = {
+  OWNER: 0,
+  ADMIN: 1,
+  MEMBER: 2
+};
+
+/**
+ * @enum {number}
+ */
+proto.org.apache.custos.user.profile.service.UserTypes = {
+  END_USER: 0,
+  COMMUNITY: 1
+};
+
+goog.object.extend(exports, proto.org.apache.custos.user.profile.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/agent-management/AgentManagementService_grpc_web_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/agent-management/AgentManagementService_grpc_web_pb.js
new file mode 100644
index 0000000..47b0b1b
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/agent-management/AgentManagementService_grpc_web_pb.js
@@ -0,0 +1,1139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+/**
+ * @fileoverview gRPC-Web generated client stub for org.apache.custos.agent.management.service
+ * @enhanceable
+ * @public
+ */
+
+// GENERATED CODE -- DO NOT EDIT!
+
+
+/* eslint-disable */
+// @ts-nocheck
+
+
+
+const grpc = {};
+grpc.web = require('grpc-web');
+
+var IamAdminService_pb = require('../../core-services/iam-admin-service/IamAdminService_pb')
+const proto = {};
+proto.org = {};
+proto.org.apache = {};
+proto.org.apache.custos = {};
+proto.org.apache.custos.agent = {};
+proto.org.apache.custos.agent.management = {};
+proto.org.apache.custos.agent.management.service = require('./AgentManagementService_pb');
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.AgentClientMetadata,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_enableAgents = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/enableAgents',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.AgentClientMetadata,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.AgentClientMetadata,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_enableAgents = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.enableAgents =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/enableAgents',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_enableAgents,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.enableAgents =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/enableAgents',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_enableAgents);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.AgentClientMetadata,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_configureAgentClient = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/configureAgentClient',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.AgentClientMetadata,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.AgentClientMetadata,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_configureAgentClient = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.configureAgentClient =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/configureAgentClient',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_configureAgentClient,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AgentClientMetadata} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.configureAgentClient =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/configureAgentClient',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_configureAgentClient);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.RegisterUserRequest,
+ *   !proto.org.apache.custos.agent.management.service.AgentRegistrationResponse>}
+ */
+const methodDescriptor_AgentManagementService_registerAndEnableAgent = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/registerAndEnableAgent',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.RegisterUserRequest,
+  proto.org.apache.custos.agent.management.service.AgentRegistrationResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.RegisterUserRequest,
+ *   !proto.org.apache.custos.agent.management.service.AgentRegistrationResponse>}
+ */
+const methodInfo_AgentManagementService_registerAndEnableAgent = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.org.apache.custos.agent.management.service.AgentRegistrationResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.agent.management.service.AgentRegistrationResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.agent.management.service.AgentRegistrationResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.registerAndEnableAgent =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/registerAndEnableAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_registerAndEnableAgent,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.agent.management.service.AgentRegistrationResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.registerAndEnableAgent =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/registerAndEnableAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_registerAndEnableAgent);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+ *   !proto.org.apache.custos.iam.service.Agent>}
+ */
+const methodDescriptor_AgentManagementService_getAgent = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/getAgent',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+  IamAdminService_pb.Agent,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.Agent.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+ *   !proto.org.apache.custos.iam.service.Agent>}
+ */
+const methodInfo_AgentManagementService_getAgent = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.Agent,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.Agent.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.Agent)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.Agent>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.getAgent =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/getAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_getAgent,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.Agent>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.getAgent =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/getAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_getAgent);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_deleteAgent = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/deleteAgent',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_deleteAgent = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.deleteAgent =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/deleteAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_deleteAgent,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.deleteAgent =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/deleteAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_deleteAgent);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_disableAgent = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/disableAgent',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_disableAgent = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.disableAgent =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/disableAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_disableAgent,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.disableAgent =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/disableAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_disableAgent);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_enableAgent = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/enableAgent',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.agent.management.service.AgentSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_enableAgent = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.enableAgent =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/enableAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_enableAgent,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.enableAgent =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/enableAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_enableAgent);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.AddUserAttributesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_addAgentAttributes = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/addAgentAttributes',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.AddUserAttributesRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.AddUserAttributesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_addAgentAttributes = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.addAgentAttributes =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/addAgentAttributes',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_addAgentAttributes,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.addAgentAttributes =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/addAgentAttributes',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_addAgentAttributes);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.DeleteUserAttributeRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_deleteAgentAttributes = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/deleteAgentAttributes',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.DeleteUserAttributeRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.DeleteUserAttributeRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_deleteAgentAttributes = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.deleteAgentAttributes =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/deleteAgentAttributes',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_deleteAgentAttributes,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.deleteAgentAttributes =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/deleteAgentAttributes',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_deleteAgentAttributes);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.AddUserRolesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_addRolesToAgent = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/addRolesToAgent',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.AddUserRolesRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.AddUserRolesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_addRolesToAgent = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.addRolesToAgent =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/addRolesToAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_addRolesToAgent,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.addRolesToAgent =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/addRolesToAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_addRolesToAgent);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.DeleteUserRolesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_deleteRolesFromAgent = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/deleteRolesFromAgent',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.DeleteUserRolesRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.DeleteUserRolesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_deleteRolesFromAgent = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.deleteRolesFromAgent =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/deleteRolesFromAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_deleteRolesFromAgent,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.deleteRolesFromAgent =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/deleteRolesFromAgent',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_deleteRolesFromAgent);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.AddProtocolMapperRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_addProtocolMapper = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/addProtocolMapper',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.AddProtocolMapperRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.AddProtocolMapperRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_addProtocolMapper = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.addProtocolMapper =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/addProtocolMapper',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_addProtocolMapper,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.addProtocolMapper =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/addProtocolMapper',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_addProtocolMapper);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_AgentManagementService_synchronizeAgentDBs = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.agent.management.service.AgentManagementService/synchronizeAgentDBs',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_AgentManagementService_synchronizeAgentDBs = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServiceClient.prototype.synchronizeAgentDBs =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/synchronizeAgentDBs',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_synchronizeAgentDBs,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.agent.management.service.AgentManagementServicePromiseClient.prototype.synchronizeAgentDBs =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.agent.management.service.AgentManagementService/synchronizeAgentDBs',
+      request,
+      metadata || {},
+      methodDescriptor_AgentManagementService_synchronizeAgentDBs);
+};
+
+
+module.exports = proto.org.apache.custos.agent.management.service;
+
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/agent-management/AgentManagementService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/agent-management/AgentManagementService_pb.js
new file mode 100644
index 0000000..a5f21d7
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/agent-management/AgentManagementService_pb.js
@@ -0,0 +1,704 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+// source: src/main/proto/AgentManagementService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+var google_protobuf_empty_pb = require('google-protobuf/google/protobuf/empty_pb.js');
+goog.object.extend(proto, google_protobuf_empty_pb);
+var IamAdminService_pb = require('../../core-services/iam-admin-service/IamAdminService_pb');
+goog.object.extend(proto, IamAdminService_pb);
+goog.exportSymbol('proto.org.apache.custos.agent.management.service.AgentRegistrationResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.agent.management.service.AgentSearchRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.agent.management.service.AgentSearchRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.agent.management.service.AgentSearchRequest.displayName = 'proto.org.apache.custos.agent.management.service.AgentSearchRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.agent.management.service.AgentRegistrationResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.displayName = 'proto.org.apache.custos.agent.management.service.AgentRegistrationResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.displayName = 'proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.agent.management.service.AgentSearchRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    clientid: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    clientsec: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    id: jspb.Message.getFieldWithDefault(msg, 7, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.agent.management.service.AgentSearchRequest}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.agent.management.service.AgentSearchRequest;
+  return proto.org.apache.custos.agent.management.service.AgentSearchRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.agent.management.service.AgentSearchRequest}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsec(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.agent.management.service.AgentSearchRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getClientsec();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} returns this
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional string accessToken = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} returns this
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string clientId = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} returns this
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string clientSec = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.getClientsec = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} returns this
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.setClientsec = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string performedBy = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} returns this
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string id = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.management.service.AgentSearchRequest} returns this
+ */
+proto.org.apache.custos.agent.management.service.AgentSearchRequest.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.agent.management.service.AgentRegistrationResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    secret: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.agent.management.service.AgentRegistrationResponse}
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.agent.management.service.AgentRegistrationResponse;
+  return proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.agent.management.service.AgentRegistrationResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.agent.management.service.AgentRegistrationResponse}
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSecret(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.agent.management.service.AgentRegistrationResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.management.service.AgentRegistrationResponse} returns this
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.prototype.getSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.management.service.AgentRegistrationResponse} returns this
+ */
+proto.org.apache.custos.agent.management.service.AgentRegistrationResponse.prototype.setSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    clientid: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest}
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest;
+  return proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest}
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest} returns this
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional string clientId = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest} returns this
+ */
+proto.org.apache.custos.agent.management.service.SynchronizeAgentDBRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+goog.object.extend(exports, proto.org.apache.custos.agent.management.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/group-management/GroupManagementService_grpc_web_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/group-management/GroupManagementService_grpc_web_pb.js
new file mode 100644
index 0000000..6b8822d
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/group-management/GroupManagementService_grpc_web_pb.js
@@ -0,0 +1,1302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+/**
+ * @fileoverview gRPC-Web generated client stub for org.apache.custos.group.management.service
+ * @enhanceable
+ * @public
+ */
+
+// GENERATED CODE -- DO NOT EDIT!
+
+
+/* eslint-disable */
+// @ts-nocheck
+
+
+
+const grpc = {};
+grpc.web = require('grpc-web');
+
+
+var UserProfileService_pb = require('../../core-services/user-profile/UserProfileService_pb')
+
+var IamAdminService_pb = require('../../core-services/iam-admin-service/IamAdminService_pb')
+const proto = {};
+proto.org = {};
+proto.org.apache = {};
+proto.org.apache.custos = {};
+proto.org.apache.custos.group = {};
+proto.org.apache.custos.group.management = {};
+proto.org.apache.custos.group.management.service = require('./GroupManagementService_pb.js');
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.GroupsRequest,
+ *   !proto.org.apache.custos.iam.service.GroupsResponse>}
+ */
+const methodDescriptor_GroupManagementService_createGroups = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/createGroups',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.GroupsRequest,
+  IamAdminService_pb.GroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupsRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.GroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.GroupsRequest,
+ *   !proto.org.apache.custos.iam.service.GroupsResponse>}
+ */
+const methodInfo_GroupManagementService_createGroups = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.GroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupsRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.GroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupsRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.GroupsResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.GroupsResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.createGroups =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/createGroups',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_createGroups,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupsRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.GroupsResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.createGroups =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/createGroups',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_createGroups);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.GroupRequest,
+ *   !proto.org.apache.custos.iam.service.GroupRepresentation>}
+ */
+const methodDescriptor_GroupManagementService_updateGroup = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/updateGroup',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.GroupRequest,
+  IamAdminService_pb.GroupRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.GroupRepresentation.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.GroupRequest,
+ *   !proto.org.apache.custos.iam.service.GroupRepresentation>}
+ */
+const methodInfo_GroupManagementService_updateGroup = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.GroupRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.GroupRepresentation.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.GroupRepresentation)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.GroupRepresentation>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.updateGroup =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/updateGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_updateGroup,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.GroupRepresentation>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.updateGroup =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/updateGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_updateGroup);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.GroupRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_GroupManagementService_deleteGroup = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/deleteGroup',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.GroupRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.GroupRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_GroupManagementService_deleteGroup = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.deleteGroup =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/deleteGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_deleteGroup,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.deleteGroup =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/deleteGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_deleteGroup);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.GroupRequest,
+ *   !proto.org.apache.custos.iam.service.GroupRepresentation>}
+ */
+const methodDescriptor_GroupManagementService_findGroup = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/findGroup',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.GroupRequest,
+  IamAdminService_pb.GroupRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.GroupRepresentation.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.GroupRequest,
+ *   !proto.org.apache.custos.iam.service.GroupRepresentation>}
+ */
+const methodInfo_GroupManagementService_findGroup = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.GroupRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.GroupRepresentation.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.GroupRepresentation)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.GroupRepresentation>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.findGroup =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/findGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_findGroup,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.GroupRepresentation>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.findGroup =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/findGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_findGroup);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.GroupRequest,
+ *   !proto.org.apache.custos.iam.service.GroupsResponse>}
+ */
+const methodDescriptor_GroupManagementService_getAllGroups = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/getAllGroups',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.GroupRequest,
+  IamAdminService_pb.GroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.GroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.GroupRequest,
+ *   !proto.org.apache.custos.iam.service.GroupsResponse>}
+ */
+const methodInfo_GroupManagementService_getAllGroups = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.GroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.GroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.GroupsResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.GroupsResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.getAllGroups =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllGroups',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllGroups,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.GroupsResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.getAllGroups =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllGroups',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllGroups);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserGroupMappingRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_GroupManagementService_addUserToGroup = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/addUserToGroup',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserGroupMappingRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserGroupMappingRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_GroupManagementService_addUserToGroup = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.addUserToGroup =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/addUserToGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_addUserToGroup,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.addUserToGroup =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/addUserToGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_addUserToGroup);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserGroupMappingRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_GroupManagementService_removeUserFromGroup = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/removeUserFromGroup',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserGroupMappingRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserGroupMappingRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_GroupManagementService_removeUserFromGroup = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.removeUserFromGroup =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/removeUserFromGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_removeUserFromGroup,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserGroupMappingRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.removeUserFromGroup =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/removeUserFromGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_removeUserFromGroup);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.profile.service.GroupToGroupMembership,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_GroupManagementService_addChildGroupToParentGroup = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/addChildGroupToParentGroup',
+  grpc.web.MethodType.UNARY,
+  UserProfileService_pb.GroupToGroupMembership,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.profile.service.GroupToGroupMembership,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_GroupManagementService_addChildGroupToParentGroup = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.addChildGroupToParentGroup =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/addChildGroupToParentGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_addChildGroupToParentGroup,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.addChildGroupToParentGroup =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/addChildGroupToParentGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_addChildGroupToParentGroup);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.profile.service.GroupToGroupMembership,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_GroupManagementService_removeChildGroupFromParentGroup = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/removeChildGroupFromParentGroup',
+  grpc.web.MethodType.UNARY,
+  UserProfileService_pb.GroupToGroupMembership,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.profile.service.GroupToGroupMembership,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_GroupManagementService_removeChildGroupFromParentGroup = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.removeChildGroupFromParentGroup =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/removeChildGroupFromParentGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_removeChildGroupFromParentGroup,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupToGroupMembership} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.removeChildGroupFromParentGroup =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/removeChildGroupFromParentGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_removeChildGroupFromParentGroup);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.profile.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>}
+ */
+const methodDescriptor_GroupManagementService_getAllGroupsOfUser = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/getAllGroupsOfUser',
+  grpc.web.MethodType.UNARY,
+  UserProfileService_pb.UserProfileRequest,
+  UserProfileService_pb.GetAllGroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllGroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.profile.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>}
+ */
+const methodInfo_GroupManagementService_getAllGroupsOfUser = new grpc.web.AbstractClientBase.MethodInfo(
+  UserProfileService_pb.GetAllGroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllGroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.user.profile.service.GetAllGroupsResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.getAllGroupsOfUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllGroupsOfUser',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllGroupsOfUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.getAllGroupsOfUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllGroupsOfUser',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllGroupsOfUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.profile.service.GroupRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>}
+ */
+const methodDescriptor_GroupManagementService_getAllParentGroupsOfGroup = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/getAllParentGroupsOfGroup',
+  grpc.web.MethodType.UNARY,
+  UserProfileService_pb.GroupRequest,
+  UserProfileService_pb.GetAllGroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllGroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.profile.service.GroupRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>}
+ */
+const methodInfo_GroupManagementService_getAllParentGroupsOfGroup = new grpc.web.AbstractClientBase.MethodInfo(
+  UserProfileService_pb.GetAllGroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllGroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.user.profile.service.GetAllGroupsResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.getAllParentGroupsOfGroup =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllParentGroupsOfGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllParentGroupsOfGroup,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.getAllParentGroupsOfGroup =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllParentGroupsOfGroup',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllParentGroupsOfGroup);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.profile.service.GroupRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse>}
+ */
+const methodDescriptor_GroupManagementService_getAllChildUsers = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/getAllChildUsers',
+  grpc.web.MethodType.UNARY,
+  UserProfileService_pb.GroupRequest,
+  UserProfileService_pb.GetAllUserProfilesResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllUserProfilesResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.profile.service.GroupRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse>}
+ */
+const methodInfo_GroupManagementService_getAllChildUsers = new grpc.web.AbstractClientBase.MethodInfo(
+  UserProfileService_pb.GetAllUserProfilesResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllUserProfilesResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.getAllChildUsers =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllChildUsers',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllChildUsers,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.getAllChildUsers =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllChildUsers',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllChildUsers);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.profile.service.GroupRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>}
+ */
+const methodDescriptor_GroupManagementService_getAllChildGroups = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/getAllChildGroups',
+  grpc.web.MethodType.UNARY,
+  UserProfileService_pb.GroupRequest,
+  UserProfileService_pb.GetAllGroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllGroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.profile.service.GroupRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>}
+ */
+const methodInfo_GroupManagementService_getAllChildGroups = new grpc.web.AbstractClientBase.MethodInfo(
+  UserProfileService_pb.GetAllGroupsResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllGroupsResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.user.profile.service.GetAllGroupsResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.getAllChildGroups =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllChildGroups',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllChildGroups,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.user.profile.service.GetAllGroupsResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.getAllChildGroups =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/getAllChildGroups',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_getAllChildGroups);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.profile.service.GroupMembership,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_GroupManagementService_changeUserMembershipType = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/changeUserMembershipType',
+  grpc.web.MethodType.UNARY,
+  UserProfileService_pb.GroupMembership,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.profile.service.GroupMembership,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_GroupManagementService_changeUserMembershipType = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.changeUserMembershipType =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/changeUserMembershipType',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_changeUserMembershipType,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.changeUserMembershipType =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/changeUserMembershipType',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_changeUserMembershipType);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.profile.service.GroupMembership,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_GroupManagementService_hasAccess = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.group.management.service.GroupManagementService/hasAccess',
+  grpc.web.MethodType.UNARY,
+  UserProfileService_pb.GroupMembership,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.profile.service.GroupMembership,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_GroupManagementService_hasAccess = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServiceClient.prototype.hasAccess =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/hasAccess',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_hasAccess,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GroupMembership} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.group.management.service.GroupManagementServicePromiseClient.prototype.hasAccess =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.group.management.service.GroupManagementService/hasAccess',
+      request,
+      metadata || {},
+      methodDescriptor_GroupManagementService_hasAccess);
+};
+
+
+module.exports = proto.org.apache.custos.group.management.service;
+
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/group-management/GroupManagementService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/group-management/GroupManagementService_pb.js
new file mode 100644
index 0000000..4d9b794
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/group-management/GroupManagementService_pb.js
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+// source: src/main/proto/GroupManagementService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+
+var UserProfileService_pb = require('../../core-services/user-profile/UserProfileService_pb');
+goog.object.extend(proto, UserProfileService_pb);
+var IamAdminService_pb = require('../../core-services/iam-admin-service/IamAdminService_pb');
+goog.object.extend(proto, IamAdminService_pb);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/identity-management/IdentityManagementService_grpc_web_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/identity-management/IdentityManagementService_grpc_web_pb.js
new file mode 100644
index 0000000..b63f348
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/identity-management/IdentityManagementService_grpc_web_pb.js
@@ -0,0 +1,988 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+/**
+ * @fileoverview gRPC-Web generated client stub for org.apache.custos.identity.management.service
+ * @enhanceable
+ * @public
+ */
+
+// GENERATED CODE -- DO NOT EDIT!
+
+
+/* eslint-disable */
+// @ts-nocheck
+
+
+
+const grpc = {};
+grpc.web = require('grpc-web');
+
+
+
+
+var IdentityService_pb = require('../../core-services/iam-admin-service/IamAdminService_pb')
+
+var google_protobuf_struct_pb = require('google-protobuf/google/protobuf/struct_pb.js')
+
+var google_protobuf_any_pb = require('google-protobuf/google/protobuf/any_pb.js')
+
+var CredentialStoreService_pb = require('../../core-services/credential-store-service/CredentialStoreService_pb.js')
+const proto = {};
+proto.org = {};
+proto.org.apache = {};
+proto.org.apache.custos = {};
+proto.org.apache.custos.identity = {};
+proto.org.apache.custos.identity.management = {};
+proto.org.apache.custos.identity.management.service = require('./IdentityManagementService_pb.js');
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.service.AuthenticationRequest,
+ *   !proto.org.apache.custos.identity.service.AuthToken>}
+ */
+const methodDescriptor_IdentityManagementService_authenticate = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/authenticate',
+  grpc.web.MethodType.UNARY,
+  IdentityService_pb.AuthenticationRequest,
+  IdentityService_pb.AuthToken,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.AuthToken.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.service.AuthenticationRequest,
+ *   !proto.org.apache.custos.identity.service.AuthToken>}
+ */
+const methodInfo_IdentityManagementService_authenticate = new grpc.web.AbstractClientBase.MethodInfo(
+  IdentityService_pb.AuthToken,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.AuthToken.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.identity.service.AuthToken)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.identity.service.AuthToken>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.authenticate =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/authenticate',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_authenticate,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.identity.service.AuthToken>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.authenticate =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/authenticate',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_authenticate);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.service.AuthToken,
+ *   !proto.org.apache.custos.identity.service.IsAuthenticateResponse>}
+ */
+const methodDescriptor_IdentityManagementService_isAuthenticated = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/isAuthenticated',
+  grpc.web.MethodType.UNARY,
+  IdentityService_pb.AuthToken,
+  IdentityService_pb.IsAuthenticateResponse,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.AuthToken} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.IsAuthenticateResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.service.AuthToken,
+ *   !proto.org.apache.custos.identity.service.IsAuthenticateResponse>}
+ */
+const methodInfo_IdentityManagementService_isAuthenticated = new grpc.web.AbstractClientBase.MethodInfo(
+  IdentityService_pb.IsAuthenticateResponse,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.AuthToken} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.IsAuthenticateResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.identity.service.IsAuthenticateResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.identity.service.IsAuthenticateResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.isAuthenticated =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/isAuthenticated',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_isAuthenticated,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.identity.service.IsAuthenticateResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.isAuthenticated =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/isAuthenticated',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_isAuthenticated);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.service.AuthToken,
+ *   !proto.org.apache.custos.identity.service.User>}
+ */
+const methodDescriptor_IdentityManagementService_getUser = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/getUser',
+  grpc.web.MethodType.UNARY,
+  IdentityService_pb.AuthToken,
+  IdentityService_pb.User,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.AuthToken} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.User.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.service.AuthToken,
+ *   !proto.org.apache.custos.identity.service.User>}
+ */
+const methodInfo_IdentityManagementService_getUser = new grpc.web.AbstractClientBase.MethodInfo(
+  IdentityService_pb.User,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.AuthToken} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.User.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.identity.service.User)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.identity.service.User>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.getUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getUser',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.identity.service.User>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.getUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getUser',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest,
+ *   !proto.org.apache.custos.identity.service.AuthToken>}
+ */
+const methodDescriptor_IdentityManagementService_getUserManagementServiceAccountAccessToken = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/getUserManagementServiceAccountAccessToken',
+  grpc.web.MethodType.UNARY,
+  IdentityService_pb.GetUserManagementSATokenRequest,
+  IdentityService_pb.AuthToken,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.AuthToken.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest,
+ *   !proto.org.apache.custos.identity.service.AuthToken>}
+ */
+const methodInfo_IdentityManagementService_getUserManagementServiceAccountAccessToken = new grpc.web.AbstractClientBase.MethodInfo(
+  IdentityService_pb.AuthToken,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.AuthToken.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.identity.service.AuthToken)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.identity.service.AuthToken>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.getUserManagementServiceAccountAccessToken =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getUserManagementServiceAccountAccessToken',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getUserManagementServiceAccountAccessToken,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.identity.service.AuthToken>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.getUserManagementServiceAccountAccessToken =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getUserManagementServiceAccountAccessToken',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getUserManagementServiceAccountAccessToken);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.management.service.EndSessionRequest,
+ *   !proto.org.apache.custos.identity.service.OperationStatus>}
+ */
+const methodDescriptor_IdentityManagementService_endUserSession = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/endUserSession',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.identity.management.service.EndSessionRequest,
+  IdentityService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.management.service.EndSessionRequest,
+ *   !proto.org.apache.custos.identity.service.OperationStatus>}
+ */
+const methodInfo_IdentityManagementService_endUserSession = new grpc.web.AbstractClientBase.MethodInfo(
+  IdentityService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.identity.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.identity.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.endUserSession =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/endUserSession',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_endUserSession,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.identity.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.endUserSession =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/endUserSession',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_endUserSession);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.management.service.AuthorizationRequest,
+ *   !proto.org.apache.custos.identity.management.service.AuthorizationResponse>}
+ */
+const methodDescriptor_IdentityManagementService_authorize = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/authorize',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.identity.management.service.AuthorizationRequest,
+  proto.org.apache.custos.identity.management.service.AuthorizationResponse,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.identity.management.service.AuthorizationResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.management.service.AuthorizationRequest,
+ *   !proto.org.apache.custos.identity.management.service.AuthorizationResponse>}
+ */
+const methodInfo_IdentityManagementService_authorize = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.org.apache.custos.identity.management.service.AuthorizationResponse,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.identity.management.service.AuthorizationResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.identity.management.service.AuthorizationResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.identity.management.service.AuthorizationResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.authorize =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/authorize',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_authorize,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.identity.management.service.AuthorizationResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.authorize =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/authorize',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_authorize);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.service.GetTokenRequest,
+ *   !proto.google.protobuf.Struct>}
+ */
+const methodDescriptor_IdentityManagementService_token = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/token',
+  grpc.web.MethodType.UNARY,
+  IdentityService_pb.GetTokenRequest,
+  google_protobuf_struct_pb.Struct,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_struct_pb.Struct.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.service.GetTokenRequest,
+ *   !proto.google.protobuf.Struct>}
+ */
+const methodInfo_IdentityManagementService_token = new grpc.web.AbstractClientBase.MethodInfo(
+  google_protobuf_struct_pb.Struct,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_struct_pb.Struct.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.google.protobuf.Struct)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.google.protobuf.Struct>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.token =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/token',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_token,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.google.protobuf.Struct>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.token =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/token',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_token);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.management.service.GetCredentialsRequest,
+ *   !proto.org.apache.custos.credential.store.service.Credentials>}
+ */
+const methodDescriptor_IdentityManagementService_getCredentials = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/getCredentials',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.identity.management.service.GetCredentialsRequest,
+  CredentialStoreService_pb.Credentials,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  CredentialStoreService_pb.Credentials.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.management.service.GetCredentialsRequest,
+ *   !proto.org.apache.custos.credential.store.service.Credentials>}
+ */
+const methodInfo_IdentityManagementService_getCredentials = new grpc.web.AbstractClientBase.MethodInfo(
+  CredentialStoreService_pb.Credentials,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  CredentialStoreService_pb.Credentials.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.credential.store.service.Credentials)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.credential.store.service.Credentials>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.getCredentials =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getCredentials',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getCredentials,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.credential.store.service.Credentials>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.getCredentials =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getCredentials',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getCredentials);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.service.GetOIDCConfiguration,
+ *   !proto.google.protobuf.Struct>}
+ */
+const methodDescriptor_IdentityManagementService_getOIDCConfiguration = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/getOIDCConfiguration',
+  grpc.web.MethodType.UNARY,
+  IdentityService_pb.GetOIDCConfiguration,
+  google_protobuf_struct_pb.Struct,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_struct_pb.Struct.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.service.GetOIDCConfiguration,
+ *   !proto.google.protobuf.Struct>}
+ */
+const methodInfo_IdentityManagementService_getOIDCConfiguration = new grpc.web.AbstractClientBase.MethodInfo(
+  google_protobuf_struct_pb.Struct,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_struct_pb.Struct.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.google.protobuf.Struct)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.google.protobuf.Struct>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.getOIDCConfiguration =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getOIDCConfiguration',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getOIDCConfiguration,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.google.protobuf.Struct>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.getOIDCConfiguration =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getOIDCConfiguration',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getOIDCConfiguration);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.management.service.GetAgentTokenRequest,
+ *   !proto.google.protobuf.Struct>}
+ */
+const methodDescriptor_IdentityManagementService_getAgentToken = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/getAgentToken',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.identity.management.service.GetAgentTokenRequest,
+  google_protobuf_struct_pb.Struct,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_struct_pb.Struct.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.management.service.GetAgentTokenRequest,
+ *   !proto.google.protobuf.Struct>}
+ */
+const methodInfo_IdentityManagementService_getAgentToken = new grpc.web.AbstractClientBase.MethodInfo(
+  google_protobuf_struct_pb.Struct,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_struct_pb.Struct.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.google.protobuf.Struct)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.google.protobuf.Struct>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.getAgentToken =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getAgentToken',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getAgentToken,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.google.protobuf.Struct>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.getAgentToken =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/getAgentToken',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_getAgentToken);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.management.service.EndSessionRequest,
+ *   !proto.org.apache.custos.identity.service.OperationStatus>}
+ */
+const methodDescriptor_IdentityManagementService_endAgentSession = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.identity.management.service.IdentityManagementService/endAgentSession',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.identity.management.service.EndSessionRequest,
+  IdentityService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.management.service.EndSessionRequest,
+ *   !proto.org.apache.custos.identity.service.OperationStatus>}
+ */
+const methodInfo_IdentityManagementService_endAgentSession = new grpc.web.AbstractClientBase.MethodInfo(
+  IdentityService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IdentityService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.identity.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.identity.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServiceClient.prototype.endAgentSession =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/endAgentSession',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_endAgentSession,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.identity.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.identity.management.service.IdentityManagementServicePromiseClient.prototype.endAgentSession =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.identity.management.service.IdentityManagementService/endAgentSession',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityManagementService_endAgentSession);
+};
+
+
+module.exports = proto.org.apache.custos.identity.management.service;
+
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/identity-management/IdentityManagementService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/identity-management/IdentityManagementService_pb.js
new file mode 100644
index 0000000..a06b5ec
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/identity-management/IdentityManagementService_pb.js
@@ -0,0 +1,1295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+// source: src/main/proto/IdentityManagementService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+
+var IdentityService_pb = require('../../core-services/identity-service/IdentityService_pb');
+goog.object.extend(proto, IdentityService_pb);
+var google_protobuf_struct_pb = require('google-protobuf/google/protobuf/struct_pb.js');
+goog.object.extend(proto, google_protobuf_struct_pb);
+var google_protobuf_any_pb = require('google-protobuf/google/protobuf/any_pb.js');
+goog.object.extend(proto, google_protobuf_any_pb);
+var CredentialStoreService_pb = require('../../core-services/credential-store-service/CredentialStoreService_pb.js');
+goog.object.extend(proto, CredentialStoreService_pb);
+goog.exportSymbol('proto.org.apache.custos.identity.management.service.AuthorizationRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.management.service.AuthorizationResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.management.service.EndSessionRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.management.service.GetAgentTokenRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.management.service.GetCredentialsRequest', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.management.service.AuthorizationRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.management.service.AuthorizationRequest.displayName = 'proto.org.apache.custos.identity.management.service.AuthorizationRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.management.service.AuthorizationResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.management.service.AuthorizationResponse.displayName = 'proto.org.apache.custos.identity.management.service.AuthorizationResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.management.service.GetCredentialsRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.management.service.GetCredentialsRequest.displayName = 'proto.org.apache.custos.identity.management.service.GetCredentialsRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.management.service.GetAgentTokenRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.displayName = 'proto.org.apache.custos.identity.management.service.GetAgentTokenRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.management.service.EndSessionRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.management.service.EndSessionRequest.displayName = 'proto.org.apache.custos.identity.management.service.EndSessionRequest';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.management.service.AuthorizationRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    clientId: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    redirectUri: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    responseType: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    scope: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    state: jspb.Message.getFieldWithDefault(msg, 7, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationRequest}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.management.service.AuthorizationRequest;
+  return proto.org.apache.custos.identity.management.service.AuthorizationRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationRequest}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRedirectUri(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setResponseType(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setScope(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setState(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.management.service.AuthorizationRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getRedirectUri();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getResponseType();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getScope();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getState();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenant_id = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string client_id = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string client_secret = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string redirect_uri = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.getRedirectUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.setRedirectUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string response_type = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.getResponseType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.setResponseType = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string scope = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.getScope = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.setScope = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string state = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.getState = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationRequest.prototype.setState = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.management.service.AuthorizationResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.management.service.AuthorizationResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    loginuri: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationResponse}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.management.service.AuthorizationResponse;
+  return proto.org.apache.custos.identity.management.service.AuthorizationResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.management.service.AuthorizationResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationResponse}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLoginuri(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.management.service.AuthorizationResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.management.service.AuthorizationResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getLoginuri();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string loginURI = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationResponse.prototype.getLoginuri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.AuthorizationResponse} returns this
+ */
+proto.org.apache.custos.identity.management.service.AuthorizationResponse.prototype.setLoginuri = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.management.service.GetCredentialsRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    credentials: (f = msg.getCredentials()) && CredentialStoreService_pb.Credentials.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest}
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.management.service.GetCredentialsRequest;
+  return proto.org.apache.custos.identity.management.service.GetCredentialsRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest}
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = new CredentialStoreService_pb.Credentials;
+      reader.readMessage(value,CredentialStoreService_pb.Credentials.deserializeBinaryFromReader);
+      msg.setCredentials(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.management.service.GetCredentialsRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getCredentials();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      CredentialStoreService_pb.Credentials.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional org.apache.custos.credential.store.service.Credentials credentials = 2;
+ * @return {?proto.org.apache.custos.credential.store.service.Credentials}
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.prototype.getCredentials = function() {
+  return /** @type{?proto.org.apache.custos.credential.store.service.Credentials} */ (
+    jspb.Message.getWrapperField(this, CredentialStoreService_pb.Credentials, 2));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.credential.store.service.Credentials|undefined} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} returns this
+*/
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.prototype.setCredentials = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.identity.management.service.GetCredentialsRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.prototype.clearCredentials = function() {
+  return this.setCredentials(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.identity.management.service.GetCredentialsRequest.prototype.hasCredentials = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    agentClientId: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    agentClientSecret: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    agentid: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    agentpassword: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    clientId: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    grantType: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    refreshToken: jspb.Message.getFieldWithDefault(msg, 8, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.management.service.GetAgentTokenRequest;
+  return proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAgentClientId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAgentClientSecret(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAgentid(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAgentpassword(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGrantType(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRefreshToken(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAgentClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getAgentClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getAgentid();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getAgentpassword();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getGrantType();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getRefreshToken();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenant_id = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string agent_client_id = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.getAgentClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.setAgentClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string agent_client_secret = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.getAgentClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.setAgentClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string agentId = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.getAgentid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.setAgentid = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string agentPassword = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.getAgentpassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.setAgentpassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string client_id = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string grant_type = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.getGrantType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.setGrantType = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string refresh_token = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.getRefreshToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.GetAgentTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.GetAgentTokenRequest.prototype.setRefreshToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.management.service.EndSessionRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    body: (f = msg.getBody()) && IdentityService_pb.EndSessionRequest.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.management.service.EndSessionRequest}
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.management.service.EndSessionRequest;
+  return proto.org.apache.custos.identity.management.service.EndSessionRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.management.service.EndSessionRequest}
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = new IdentityService_pb.EndSessionRequest;
+      reader.readMessage(value,IdentityService_pb.EndSessionRequest.deserializeBinaryFromReader);
+      msg.setBody(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.management.service.EndSessionRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.management.service.EndSessionRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getBody();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      IdentityService_pb.EndSessionRequest.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.management.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional org.apache.custos.identity.service.EndSessionRequest body = 2;
+ * @return {?proto.org.apache.custos.identity.service.EndSessionRequest}
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.prototype.getBody = function() {
+  return /** @type{?proto.org.apache.custos.identity.service.EndSessionRequest} */ (
+    jspb.Message.getWrapperField(this, IdentityService_pb.EndSessionRequest, 2));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.identity.service.EndSessionRequest|undefined} value
+ * @return {!proto.org.apache.custos.identity.management.service.EndSessionRequest} returns this
+*/
+proto.org.apache.custos.identity.management.service.EndSessionRequest.prototype.setBody = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.identity.management.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.prototype.clearBody = function() {
+  return this.setBody(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.identity.management.service.EndSessionRequest.prototype.hasBody = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+goog.object.extend(exports, proto.org.apache.custos.identity.management.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/resource-secret-management/ResourceSecretManagementService_grpc_web_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/resource-secret-management/ResourceSecretManagementService_grpc_web_pb.js
new file mode 100644
index 0000000..e0b7c5c
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/resource-secret-management/ResourceSecretManagementService_grpc_web_pb.js
@@ -0,0 +1,1149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+/**
+ * @fileoverview gRPC-Web generated client stub for org.apache.custos.resource.secret.management.service
+ * @enhanceable
+ * @public
+ */
+
+// GENERATED CODE -- DO NOT EDIT!
+
+
+/* eslint-disable */
+// @ts-nocheck
+
+
+
+const grpc = {};
+grpc.web = require('grpc-web');
+
+
+// var google_api_annotations_pb = require('../../../google/api/annotations_pb.js')
+//
+// var google_protobuf_empty_pb = require('google-protobuf/google/protobuf/empty_pb.js')
+
+var google_protobuf_struct_pb = require('google-protobuf/google/protobuf/struct_pb.js')
+
+var ResourceSecretService_pb = require('./../../core-services/resource-secret-service/ResourceSecretService_pb.js')
+
+var IdentityService_pb = require('./../../core-services/identity-service/IdentityService_pb.js')
+const proto = {};
+proto.org = {};
+proto.org.apache = {};
+proto.org.apache.custos = {};
+proto.org.apache.custos.resource = {};
+proto.org.apache.custos.resource.secret = {};
+proto.org.apache.custos.resource.secret.management = {};
+proto.org.apache.custos.resource.secret.management.service = require('./ResourceSecretManagementService_pb');
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.GetSecretRequest,
+ *   !proto.org.apache.custos.resource.secret.service.SecretMetadata>}
+ */
+const methodDescriptor_ResourceSecretManagementService_getSecret = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSecret',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.GetSecretRequest,
+  ResourceSecretService_pb.SecretMetadata,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.SecretMetadata.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.GetSecretRequest,
+ *   !proto.org.apache.custos.resource.secret.service.SecretMetadata>}
+ */
+const methodInfo_ResourceSecretManagementService_getSecret = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.SecretMetadata,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.SecretMetadata.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.SecretMetadata)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.SecretMetadata>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.getSecret =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSecret',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getSecret,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetSecretRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.SecretMetadata>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.getSecret =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSecret',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getSecret);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.identity.service.GetJWKSRequest,
+ *   !proto.google.protobuf.Struct>}
+ */
+const methodDescriptor_ResourceSecretManagementService_getJWKS = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getJWKS',
+  grpc.web.MethodType.UNARY,
+  IdentityService_pb.GetJWKSRequest,
+  google_protobuf_struct_pb.Struct,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_struct_pb.Struct.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.identity.service.GetJWKSRequest,
+ *   !proto.google.protobuf.Struct>}
+ */
+const methodInfo_ResourceSecretManagementService_getJWKS = new grpc.web.AbstractClientBase.MethodInfo(
+  google_protobuf_struct_pb.Struct,
+  /**
+   * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_struct_pb.Struct.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.google.protobuf.Struct)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.google.protobuf.Struct>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.getJWKS =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getJWKS',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getJWKS,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.google.protobuf.Struct>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.getJWKS =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getJWKS',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getJWKS);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.SecretMetadata>}
+ */
+const methodDescriptor_ResourceSecretManagementService_getResourceCredentialSummary = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getResourceCredentialSummary',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.GetResourceCredentialByTokenRequest,
+  ResourceSecretService_pb.SecretMetadata,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.SecretMetadata.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.SecretMetadata>}
+ */
+const methodInfo_ResourceSecretManagementService_getResourceCredentialSummary = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.SecretMetadata,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.SecretMetadata.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.SecretMetadata)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.SecretMetadata>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.getResourceCredentialSummary =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getResourceCredentialSummary',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getResourceCredentialSummary,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.SecretMetadata>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.getResourceCredentialSummary =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getResourceCredentialSummary',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getResourceCredentialSummary);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest,
+ *   !proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries>}
+ */
+const methodDescriptor_ResourceSecretManagementService_getAllResourceCredentialSummaries = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getAllResourceCredentialSummaries',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.GetResourceCredentialSummariesRequest,
+  ResourceSecretService_pb.ResourceCredentialSummaries,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.ResourceCredentialSummaries.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest,
+ *   !proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries>}
+ */
+const methodInfo_ResourceSecretManagementService_getAllResourceCredentialSummaries = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.ResourceCredentialSummaries,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.ResourceCredentialSummaries.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.getAllResourceCredentialSummaries =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getAllResourceCredentialSummaries',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getAllResourceCredentialSummaries,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.ResourceCredentialSummaries>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.getAllResourceCredentialSummaries =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getAllResourceCredentialSummaries',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getAllResourceCredentialSummaries);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.SSHCredential,
+ *   !proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>}
+ */
+const methodDescriptor_ResourceSecretManagementService_addSSHCredential = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addSSHCredential',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.SSHCredential,
+  ResourceSecretService_pb.AddResourceCredentialResponse,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.SSHCredential} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.AddResourceCredentialResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.SSHCredential,
+ *   !proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>}
+ */
+const methodInfo_ResourceSecretManagementService_addSSHCredential = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.AddResourceCredentialResponse,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.SSHCredential} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.AddResourceCredentialResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.SSHCredential} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.addSSHCredential =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addSSHCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_addSSHCredential,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.SSHCredential} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.addSSHCredential =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addSSHCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_addSSHCredential);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.PasswordCredential,
+ *   !proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>}
+ */
+const methodDescriptor_ResourceSecretManagementService_addPasswordCredential = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addPasswordCredential',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.PasswordCredential,
+  ResourceSecretService_pb.AddResourceCredentialResponse,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.PasswordCredential} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.AddResourceCredentialResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.PasswordCredential,
+ *   !proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>}
+ */
+const methodInfo_ResourceSecretManagementService_addPasswordCredential = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.AddResourceCredentialResponse,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.PasswordCredential} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.AddResourceCredentialResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.PasswordCredential} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.addPasswordCredential =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addPasswordCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_addPasswordCredential,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.PasswordCredential} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.addPasswordCredential =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addPasswordCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_addPasswordCredential);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.CertificateCredential,
+ *   !proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>}
+ */
+const methodDescriptor_ResourceSecretManagementService_addCertificateCredential = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addCertificateCredential',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.CertificateCredential,
+  ResourceSecretService_pb.AddResourceCredentialResponse,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.CertificateCredential} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.AddResourceCredentialResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.CertificateCredential,
+ *   !proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>}
+ */
+const methodInfo_ResourceSecretManagementService_addCertificateCredential = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.AddResourceCredentialResponse,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.CertificateCredential} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.AddResourceCredentialResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.CertificateCredential} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.addCertificateCredential =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addCertificateCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_addCertificateCredential,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.CertificateCredential} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.AddResourceCredentialResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.addCertificateCredential =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addCertificateCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_addCertificateCredential);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.SSHCredential>}
+ */
+const methodDescriptor_ResourceSecretManagementService_getSSHCredential = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSSHCredential',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.GetResourceCredentialByTokenRequest,
+  ResourceSecretService_pb.SSHCredential,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.SSHCredential.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.SSHCredential>}
+ */
+const methodInfo_ResourceSecretManagementService_getSSHCredential = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.SSHCredential,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.SSHCredential.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.SSHCredential)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.SSHCredential>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.getSSHCredential =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSSHCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getSSHCredential,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.SSHCredential>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.getSSHCredential =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSSHCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getSSHCredential);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.PasswordCredential>}
+ */
+const methodDescriptor_ResourceSecretManagementService_getPasswordCredential = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getPasswordCredential',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.GetResourceCredentialByTokenRequest,
+  ResourceSecretService_pb.PasswordCredential,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.PasswordCredential.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.PasswordCredential>}
+ */
+const methodInfo_ResourceSecretManagementService_getPasswordCredential = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.PasswordCredential,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.PasswordCredential.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.PasswordCredential)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.PasswordCredential>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.getPasswordCredential =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getPasswordCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getPasswordCredential,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.PasswordCredential>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.getPasswordCredential =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getPasswordCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getPasswordCredential);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.CertificateCredential>}
+ */
+const methodDescriptor_ResourceSecretManagementService_getCertificateCredential = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getCertificateCredential',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.GetResourceCredentialByTokenRequest,
+  ResourceSecretService_pb.CertificateCredential,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.CertificateCredential.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.CertificateCredential>}
+ */
+const methodInfo_ResourceSecretManagementService_getCertificateCredential = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.CertificateCredential,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.CertificateCredential.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.CertificateCredential)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.CertificateCredential>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.getCertificateCredential =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getCertificateCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getCertificateCredential,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.CertificateCredential>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.getCertificateCredential =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getCertificateCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_getCertificateCredential);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>}
+ */
+const methodDescriptor_ResourceSecretManagementService_deleteSSHCredential = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteSSHCredential',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.GetResourceCredentialByTokenRequest,
+  ResourceSecretService_pb.ResourceCredentialOperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.ResourceCredentialOperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>}
+ */
+const methodInfo_ResourceSecretManagementService_deleteSSHCredential = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.ResourceCredentialOperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.ResourceCredentialOperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.deleteSSHCredential =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteSSHCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_deleteSSHCredential,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.deleteSSHCredential =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteSSHCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_deleteSSHCredential);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>}
+ */
+const methodDescriptor_ResourceSecretManagementService_deletePWDCredential = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deletePWDCredential',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.GetResourceCredentialByTokenRequest,
+  ResourceSecretService_pb.ResourceCredentialOperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.ResourceCredentialOperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>}
+ */
+const methodInfo_ResourceSecretManagementService_deletePWDCredential = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.ResourceCredentialOperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.ResourceCredentialOperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.deletePWDCredential =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deletePWDCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_deletePWDCredential,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.deletePWDCredential =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deletePWDCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_deletePWDCredential);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>}
+ */
+const methodDescriptor_ResourceSecretManagementService_deleteCertificateCredential = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteCertificateCredential',
+  grpc.web.MethodType.UNARY,
+  ResourceSecretService_pb.GetResourceCredentialByTokenRequest,
+  ResourceSecretService_pb.ResourceCredentialOperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.ResourceCredentialOperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest,
+ *   !proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>}
+ */
+const methodInfo_ResourceSecretManagementService_deleteCertificateCredential = new grpc.web.AbstractClientBase.MethodInfo(
+  ResourceSecretService_pb.ResourceCredentialOperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  ResourceSecretService_pb.ResourceCredentialOperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceClient.prototype.deleteCertificateCredential =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteCertificateCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_deleteCertificateCredential,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.resource.secret.management.service.ResourceSecretManagementServicePromiseClient.prototype.deleteCertificateCredential =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteCertificateCredential',
+      request,
+      metadata || {},
+      methodDescriptor_ResourceSecretManagementService_deleteCertificateCredential);
+};
+
+
+module.exports = proto.org.apache.custos.resource.secret.management.service;
+
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/resource-secret-management/ResourceSecretManagementService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/resource-secret-management/ResourceSecretManagementService_pb.js
new file mode 100644
index 0000000..a7d46c3
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/resource-secret-management/ResourceSecretManagementService_pb.js
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+// source: src/main/proto/ResourceSecretManagementService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+
+var goog = jspb;
+var global = Function('return this')();
+
+global.XMLHttpRequest = require('xhr2');
+
+var google_protobuf_empty_pb = require('google-protobuf/google/protobuf/empty_pb.js');
+goog.object.extend(proto, google_protobuf_empty_pb);
+var google_protobuf_struct_pb = require('google-protobuf/google/protobuf/struct_pb.js');
+goog.object.extend(proto, google_protobuf_struct_pb);
+var ResourceSecretService_pb = require('./../../core-services/resource-secret-service/ResourceSecretService_pb.js');
+goog.object.extend(proto, ResourceSecretService_pb);
+var IdentityService_pb = require('./../../core-services/identity-service/IdentityService_pb.js');
+goog.object.extend(proto, IdentityService_pb);
+
+// var gopt = require('google-proto-files');
+// goog.object.extend(proto, gopt);
+//
+// var google_api_annotations_pb = require('google-proto-files/google/api/annotations_pb.js');
+// goog.object.extend(proto, google_api_annotations_pb);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/tenant-management/TenantManagementService_grpc_web_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/tenant-management/TenantManagementService_grpc_web_pb.js
new file mode 100644
index 0000000..4e4da23
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/tenant-management/TenantManagementService_grpc_web_pb.js
@@ -0,0 +1,1129 @@
+/**
+ * @fileoverview gRPC-Web generated client stub for org.apache.custos.tenant.management.service
+ * @enhanceable
+ * @public
+ */
+
+// GENERATED CODE -- DO NOT EDIT!
+
+
+/* eslint-disable */
+// @ts-nocheck
+
+
+
+const grpc = {};
+grpc.web = require('grpc-web');
+
+
+var google_api_annotations_pb = require('../../../google/api/annotations_pb.js')
+
+var TenantProfileService_pb = require('../../../TenantProfileService_pb.js')
+
+var google_rpc_error_details_pb = require('../../../google/rpc/error_details_pb.js')
+
+var google_protobuf_empty_pb = require('google-protobuf/google/protobuf/empty_pb.js')
+
+var IamAdminService_pb = require('../../../IamAdminService_pb.js')
+const proto = {};
+proto.org = {};
+proto.org.apache = {};
+proto.org.apache.custos = {};
+proto.org.apache.custos.tenant = {};
+proto.org.apache.custos.tenant.management = {};
+proto.org.apache.custos.tenant.management.service = require('./TenantManagementService_pb.js');
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.profile.service.Tenant,
+ *   !proto.org.apache.custos.tenant.management.service.CreateTenantResponse>}
+ */
+const methodDescriptor_TenantManagementService_createTenant = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/createTenant',
+  grpc.web.MethodType.UNARY,
+  TenantProfileService_pb.Tenant,
+  proto.org.apache.custos.tenant.management.service.CreateTenantResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.Tenant} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.tenant.management.service.CreateTenantResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.profile.service.Tenant,
+ *   !proto.org.apache.custos.tenant.management.service.CreateTenantResponse>}
+ */
+const methodInfo_TenantManagementService_createTenant = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.org.apache.custos.tenant.management.service.CreateTenantResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.Tenant} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.tenant.management.service.CreateTenantResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.Tenant} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.tenant.management.service.CreateTenantResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.tenant.management.service.CreateTenantResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.createTenant =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/createTenant',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_createTenant,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.Tenant} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.tenant.management.service.CreateTenantResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.createTenant =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/createTenant',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_createTenant);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.management.service.GetTenantRequest,
+ *   !proto.org.apache.custos.tenant.management.service.GetTenantResponse>}
+ */
+const methodDescriptor_TenantManagementService_getTenant = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/getTenant',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.tenant.management.service.GetTenantRequest,
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.management.service.GetTenantRequest,
+ *   !proto.org.apache.custos.tenant.management.service.GetTenantResponse>}
+ */
+const methodInfo_TenantManagementService_getTenant = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.tenant.management.service.GetTenantResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.tenant.management.service.GetTenantResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.getTenant =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getTenant',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getTenant,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.tenant.management.service.GetTenantResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.getTenant =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getTenant',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getTenant);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.management.service.UpdateTenantRequest,
+ *   !proto.org.apache.custos.tenant.management.service.GetTenantResponse>}
+ */
+const methodDescriptor_TenantManagementService_updateTenant = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/updateTenant',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.tenant.management.service.UpdateTenantRequest,
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.management.service.UpdateTenantRequest,
+ *   !proto.org.apache.custos.tenant.management.service.GetTenantResponse>}
+ */
+const methodInfo_TenantManagementService_updateTenant = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.tenant.management.service.GetTenantResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.tenant.management.service.GetTenantResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.updateTenant =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/updateTenant',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_updateTenant,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.tenant.management.service.GetTenantResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.updateTenant =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/updateTenant',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_updateTenant);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.management.service.DeleteTenantRequest,
+ *   !proto.google.protobuf.Empty>}
+ */
+const methodDescriptor_TenantManagementService_deleteTenant = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/deleteTenant',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.tenant.management.service.DeleteTenantRequest,
+  google_protobuf_empty_pb.Empty,
+  /**
+   * @param {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_empty_pb.Empty.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.management.service.DeleteTenantRequest,
+ *   !proto.google.protobuf.Empty>}
+ */
+const methodInfo_TenantManagementService_deleteTenant = new grpc.web.AbstractClientBase.MethodInfo(
+  google_protobuf_empty_pb.Empty,
+  /**
+   * @param {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  google_protobuf_empty_pb.Empty.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.google.protobuf.Empty)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.google.protobuf.Empty>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.deleteTenant =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/deleteTenant',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_deleteTenant,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.google.protobuf.Empty>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.deleteTenant =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/deleteTenant',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_deleteTenant);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.AddRolesRequest,
+ *   !proto.org.apache.custos.iam.service.AllRoles>}
+ */
+const methodDescriptor_TenantManagementService_addTenantRoles = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/addTenantRoles',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.AddRolesRequest,
+  IamAdminService_pb.AllRoles,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.AllRoles.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.AddRolesRequest,
+ *   !proto.org.apache.custos.iam.service.AllRoles>}
+ */
+const methodInfo_TenantManagementService_addTenantRoles = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.AllRoles,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.AllRoles.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.AllRoles)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.AllRoles>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.addTenantRoles =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/addTenantRoles',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_addTenantRoles,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.AllRoles>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.addTenantRoles =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/addTenantRoles',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_addTenantRoles);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.AddProtocolMapperRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_TenantManagementService_addProtocolMapper = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/addProtocolMapper',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.AddProtocolMapperRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.AddProtocolMapperRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_TenantManagementService_addProtocolMapper = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.addProtocolMapper =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/addProtocolMapper',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_addProtocolMapper,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddProtocolMapperRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.addProtocolMapper =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/addProtocolMapper',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_addProtocolMapper);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.EventPersistenceRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_TenantManagementService_configureEventPersistence = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/configureEventPersistence',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.EventPersistenceRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.EventPersistenceRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.EventPersistenceRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_TenantManagementService_configureEventPersistence = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.EventPersistenceRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.EventPersistenceRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.configureEventPersistence =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/configureEventPersistence',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_configureEventPersistence,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.EventPersistenceRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.configureEventPersistence =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/configureEventPersistence',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_configureEventPersistence);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse>}
+ */
+const methodDescriptor_TenantManagementService_updateTenantStatus = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/updateTenantStatus',
+  grpc.web.MethodType.UNARY,
+  TenantProfileService_pb.UpdateStatusRequest,
+  TenantProfileService_pb.UpdateStatusResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.UpdateStatusResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse>}
+ */
+const methodInfo_TenantManagementService_updateTenantStatus = new grpc.web.AbstractClientBase.MethodInfo(
+  TenantProfileService_pb.UpdateStatusResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.UpdateStatusResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.updateTenantStatus =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/updateTenantStatus',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_updateTenantStatus,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.UpdateStatusRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.tenant.profile.service.UpdateStatusResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.updateTenantStatus =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/updateTenantStatus',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_updateTenantStatus);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.profile.service.GetTenantsRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse>}
+ */
+const methodDescriptor_TenantManagementService_getAllTenants = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/getAllTenants',
+  grpc.web.MethodType.UNARY,
+  TenantProfileService_pb.GetTenantsRequest,
+  TenantProfileService_pb.GetAllTenantsResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetAllTenantsResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.profile.service.GetTenantsRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse>}
+ */
+const methodInfo_TenantManagementService_getAllTenants = new grpc.web.AbstractClientBase.MethodInfo(
+  TenantProfileService_pb.GetAllTenantsResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetAllTenantsResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.getAllTenants =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getAllTenants',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getAllTenants,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.getAllTenants =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getAllTenants',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getAllTenants);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.profile.service.GetTenantsRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse>}
+ */
+const methodDescriptor_TenantManagementService_getChildTenants = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/getChildTenants',
+  grpc.web.MethodType.UNARY,
+  TenantProfileService_pb.GetTenantsRequest,
+  TenantProfileService_pb.GetAllTenantsResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetAllTenantsResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.profile.service.GetTenantsRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse>}
+ */
+const methodInfo_TenantManagementService_getChildTenants = new grpc.web.AbstractClientBase.MethodInfo(
+  TenantProfileService_pb.GetAllTenantsResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetAllTenantsResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.getChildTenants =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getChildTenants',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getChildTenants,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetTenantsRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.tenant.profile.service.GetAllTenantsResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.getChildTenants =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getChildTenants',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getChildTenants);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse>}
+ */
+const methodDescriptor_TenantManagementService_getAllTenantsForUser = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/getAllTenantsForUser',
+  grpc.web.MethodType.UNARY,
+  TenantProfileService_pb.GetAllTenantsForUserRequest,
+  TenantProfileService_pb.GetAllTenantsForUserResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetAllTenantsForUserResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse>}
+ */
+const methodInfo_TenantManagementService_getAllTenantsForUser = new grpc.web.AbstractClientBase.MethodInfo(
+  TenantProfileService_pb.GetAllTenantsForUserResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetAllTenantsForUserResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.getAllTenantsForUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getAllTenantsForUser',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getAllTenantsForUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.getAllTenantsForUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getAllTenantsForUser',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getAllTenantsForUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse>}
+ */
+const methodDescriptor_TenantManagementService_getTenantStatusUpdateAuditTrail = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/getTenantStatusUpdateAuditTrail',
+  grpc.web.MethodType.UNARY,
+  TenantProfileService_pb.GetAuditTrailRequest,
+  TenantProfileService_pb.GetStatusUpdateAuditTrailResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetStatusUpdateAuditTrailResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse>}
+ */
+const methodInfo_TenantManagementService_getTenantStatusUpdateAuditTrail = new grpc.web.AbstractClientBase.MethodInfo(
+  TenantProfileService_pb.GetStatusUpdateAuditTrailResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetStatusUpdateAuditTrailResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.getTenantStatusUpdateAuditTrail =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getTenantStatusUpdateAuditTrail',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getTenantStatusUpdateAuditTrail,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.getTenantStatusUpdateAuditTrail =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getTenantStatusUpdateAuditTrail',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getTenantStatusUpdateAuditTrail);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse>}
+ */
+const methodDescriptor_TenantManagementService_getTenantAttributeUpdateAuditTrail = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.tenant.management.service.TenantManagementService/getTenantAttributeUpdateAuditTrail',
+  grpc.web.MethodType.UNARY,
+  TenantProfileService_pb.GetAuditTrailRequest,
+  TenantProfileService_pb.GetAttributeUpdateAuditTrailResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetAttributeUpdateAuditTrailResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest,
+ *   !proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse>}
+ */
+const methodInfo_TenantManagementService_getTenantAttributeUpdateAuditTrail = new grpc.web.AbstractClientBase.MethodInfo(
+  TenantProfileService_pb.GetAttributeUpdateAuditTrailResponse,
+  /**
+   * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  TenantProfileService_pb.GetAttributeUpdateAuditTrailResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServiceClient.prototype.getTenantAttributeUpdateAuditTrail =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getTenantAttributeUpdateAuditTrail',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getTenantAttributeUpdateAuditTrail,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.tenant.profile.service.GetAuditTrailRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.tenant.management.service.TenantManagementServicePromiseClient.prototype.getTenantAttributeUpdateAuditTrail =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.tenant.management.service.TenantManagementService/getTenantAttributeUpdateAuditTrail',
+      request,
+      metadata || {},
+      methodDescriptor_TenantManagementService_getTenantAttributeUpdateAuditTrail);
+};
+
+
+module.exports = proto.org.apache.custos.tenant.management.service;
+
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/tenant-management/TenantManagementService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/tenant-management/TenantManagementService_pb.js
new file mode 100644
index 0000000..47957e1
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/tenant-management/TenantManagementService_pb.js
@@ -0,0 +1,2890 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+// source: src/main/proto/TenantManagementService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+
+var TenantProfileService_pb = require('../../core-services/tenant-profile/TenantProfileService_pb.js');
+goog.object.extend(proto, TenantProfileService_pb);
+var google_protobuf_empty_pb = require('google-protobuf/google/protobuf/empty_pb.js');
+goog.object.extend(proto, google_protobuf_empty_pb);
+var IamAdminService_pb = require('../../core-services/iam-admin-service/IamAdminService_pb.js');
+goog.object.extend(proto, IamAdminService_pb);
+goog.exportSymbol('proto.org.apache.custos.tenant.management.service.CreateTenantResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.management.service.Credentials', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.management.service.DeleteTenantRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.management.service.GetCredentialsRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.management.service.GetCredentialsResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.management.service.GetTenantRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.management.service.GetTenantResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.tenant.management.service.UpdateTenantRequest', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.management.service.CreateTenantResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.management.service.CreateTenantResponse.displayName = 'proto.org.apache.custos.tenant.management.service.CreateTenantResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.tenant.management.service.GetTenantResponse.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.management.service.GetTenantResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse.displayName = 'proto.org.apache.custos.tenant.management.service.GetTenantResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.management.service.GetTenantRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.management.service.GetTenantRequest.displayName = 'proto.org.apache.custos.tenant.management.service.GetTenantRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.management.service.Credentials = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.management.service.Credentials, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.management.service.Credentials.displayName = 'proto.org.apache.custos.tenant.management.service.Credentials';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.management.service.UpdateTenantRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.displayName = 'proto.org.apache.custos.tenant.management.service.UpdateTenantRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.management.service.DeleteTenantRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.displayName = 'proto.org.apache.custos.tenant.management.service.DeleteTenantRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.management.service.GetCredentialsRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.displayName = 'proto.org.apache.custos.tenant.management.service.GetCredentialsRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.tenant.management.service.GetCredentialsResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.displayName = 'proto.org.apache.custos.tenant.management.service.GetCredentialsResponse';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.management.service.CreateTenantResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    isActivated: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
+    clientIdIssuedAt: jspb.Message.getFloatingPointFieldWithDefault(msg, 4, 0.0),
+    clientSecretExpiresAt: jspb.Message.getFloatingPointFieldWithDefault(msg, 5, 0.0),
+    registrationClientUri: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    tokenEndpointAuthMethod: jspb.Message.getFieldWithDefault(msg, 17, ""),
+    msg: jspb.Message.getFieldWithDefault(msg, 7, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.management.service.CreateTenantResponse;
+  return proto.org.apache.custos.tenant.management.service.CreateTenantResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 3:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsActivated(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setClientIdIssuedAt(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setClientSecretExpiresAt(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRegistrationClientUri(value);
+      break;
+    case 17:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTokenEndpointAuthMethod(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMsg(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.management.service.CreateTenantResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getIsActivated();
+  if (f) {
+    writer.writeBool(
+      3,
+      f
+    );
+  }
+  f = message.getClientIdIssuedAt();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      4,
+      f
+    );
+  }
+  f = message.getClientSecretExpiresAt();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      5,
+      f
+    );
+  }
+  f = message.getRegistrationClientUri();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getTokenEndpointAuthMethod();
+  if (f.length > 0) {
+    writer.writeString(
+      17,
+      f
+    );
+  }
+  f = message.getMsg();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string client_secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional bool is_activated = 3;
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.getIsActivated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.setIsActivated = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 3, value);
+};
+
+
+/**
+ * optional double client_id_issued_at = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.getClientIdIssuedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 4, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.setClientIdIssuedAt = function(value) {
+  return jspb.Message.setProto3FloatField(this, 4, value);
+};
+
+
+/**
+ * optional double client_secret_expires_at = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.getClientSecretExpiresAt = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 5, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.setClientSecretExpiresAt = function(value) {
+  return jspb.Message.setProto3FloatField(this, 5, value);
+};
+
+
+/**
+ * optional string registration_client_uri = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.getRegistrationClientUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.setRegistrationClientUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string token_endpoint_auth_method = 17;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.getTokenEndpointAuthMethod = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 17, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.setTokenEndpointAuthMethod = function(value) {
+  return jspb.Message.setProto3StringField(this, 17, value);
+};
+
+
+/**
+ * optional string msg = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.getMsg = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.CreateTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.CreateTenantResponse.prototype.setMsg = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.repeatedFields_ = [7,8,9];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.management.service.GetTenantResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientName: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    requesterEmail: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    adminFirstName: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    adminLastName: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    adminEmail: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    contactsList: (f = jspb.Message.getRepeatedField(msg, 7)) == null ? undefined : f,
+    redirectUrisList: (f = jspb.Message.getRepeatedField(msg, 8)) == null ? undefined : f,
+    grantTypesList: (f = jspb.Message.getRepeatedField(msg, 9)) == null ? undefined : f,
+    clientIdIssuedAt: jspb.Message.getFloatingPointFieldWithDefault(msg, 10, 0.0),
+    clientUri: jspb.Message.getFieldWithDefault(msg, 11, ""),
+    scope: jspb.Message.getFieldWithDefault(msg, 12, ""),
+    domain: jspb.Message.getFieldWithDefault(msg, 13, ""),
+    comment: jspb.Message.getFieldWithDefault(msg, 14, ""),
+    logoUri: jspb.Message.getFieldWithDefault(msg, 15, ""),
+    applicationType: jspb.Message.getFieldWithDefault(msg, 16, ""),
+    jwksUri: jspb.Message.getFieldWithDefault(msg, 17, ""),
+    exampleExtensionParameter: jspb.Message.getFieldWithDefault(msg, 18, ""),
+    tosUri: jspb.Message.getFieldWithDefault(msg, 19, ""),
+    policyUri: jspb.Message.getFieldWithDefault(msg, 20, ""),
+    jwksMap: (f = msg.getJwksMap()) ? f.toObject(includeInstance, undefined) : [],
+    softwareId: jspb.Message.getFieldWithDefault(msg, 22, ""),
+    softwareVersion: jspb.Message.getFieldWithDefault(msg, 23, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.management.service.GetTenantResponse;
+  return proto.org.apache.custos.tenant.management.service.GetTenantResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientName(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRequesterEmail(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminFirstName(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminLastName(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAdminEmail(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addContacts(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRedirectUris(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addGrantTypes(value);
+      break;
+    case 10:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setClientIdIssuedAt(value);
+      break;
+    case 11:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientUri(value);
+      break;
+    case 12:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setScope(value);
+      break;
+    case 13:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDomain(value);
+      break;
+    case 14:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setComment(value);
+      break;
+    case 15:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLogoUri(value);
+      break;
+    case 16:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setApplicationType(value);
+      break;
+    case 17:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setJwksUri(value);
+      break;
+    case 18:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setExampleExtensionParameter(value);
+      break;
+    case 19:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTosUri(value);
+      break;
+    case 20:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPolicyUri(value);
+      break;
+    case 21:
+      var value = msg.getJwksMap();
+      reader.readMessage(value, function(message, reader) {
+        jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString, null, "", "");
+         });
+      break;
+    case 22:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSoftwareId(value);
+      break;
+    case 23:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSoftwareVersion(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.management.service.GetTenantResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientName();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getRequesterEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getAdminFirstName();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getAdminLastName();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getAdminEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getContactsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      7,
+      f
+    );
+  }
+  f = message.getRedirectUrisList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      8,
+      f
+    );
+  }
+  f = message.getGrantTypesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      9,
+      f
+    );
+  }
+  f = message.getClientIdIssuedAt();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      10,
+      f
+    );
+  }
+  f = message.getClientUri();
+  if (f.length > 0) {
+    writer.writeString(
+      11,
+      f
+    );
+  }
+  f = message.getScope();
+  if (f.length > 0) {
+    writer.writeString(
+      12,
+      f
+    );
+  }
+  f = message.getDomain();
+  if (f.length > 0) {
+    writer.writeString(
+      13,
+      f
+    );
+  }
+  f = message.getComment();
+  if (f.length > 0) {
+    writer.writeString(
+      14,
+      f
+    );
+  }
+  f = message.getLogoUri();
+  if (f.length > 0) {
+    writer.writeString(
+      15,
+      f
+    );
+  }
+  f = message.getApplicationType();
+  if (f.length > 0) {
+    writer.writeString(
+      16,
+      f
+    );
+  }
+  f = message.getJwksUri();
+  if (f.length > 0) {
+    writer.writeString(
+      17,
+      f
+    );
+  }
+  f = message.getExampleExtensionParameter();
+  if (f.length > 0) {
+    writer.writeString(
+      18,
+      f
+    );
+  }
+  f = message.getTosUri();
+  if (f.length > 0) {
+    writer.writeString(
+      19,
+      f
+    );
+  }
+  f = message.getPolicyUri();
+  if (f.length > 0) {
+    writer.writeString(
+      20,
+      f
+    );
+  }
+  f = message.getJwksMap(true);
+  if (f && f.getLength() > 0) {
+    f.serializeBinary(21, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString);
+  }
+  f = message.getSoftwareId();
+  if (f.length > 0) {
+    writer.writeString(
+      22,
+      f
+    );
+  }
+  f = message.getSoftwareVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      23,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string client_name = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getClientName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setClientName = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string requester_email = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getRequesterEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setRequesterEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string admin_first_name = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getAdminFirstName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setAdminFirstName = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string admin_last_name = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getAdminLastName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setAdminLastName = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string admin_email = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getAdminEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setAdminEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * repeated string contacts = 7;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getContactsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 7));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setContactsList = function(value) {
+  return jspb.Message.setField(this, 7, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.addContacts = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 7, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.clearContactsList = function() {
+  return this.setContactsList([]);
+};
+
+
+/**
+ * repeated string redirect_uris = 8;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getRedirectUrisList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 8));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setRedirectUrisList = function(value) {
+  return jspb.Message.setField(this, 8, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.addRedirectUris = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 8, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.clearRedirectUrisList = function() {
+  return this.setRedirectUrisList([]);
+};
+
+
+/**
+ * repeated string grant_types = 9;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getGrantTypesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 9));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setGrantTypesList = function(value) {
+  return jspb.Message.setField(this, 9, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.addGrantTypes = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 9, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.clearGrantTypesList = function() {
+  return this.setGrantTypesList([]);
+};
+
+
+/**
+ * optional double client_id_issued_at = 10;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getClientIdIssuedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 10, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setClientIdIssuedAt = function(value) {
+  return jspb.Message.setProto3FloatField(this, 10, value);
+};
+
+
+/**
+ * optional string client_uri = 11;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getClientUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 11, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setClientUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 11, value);
+};
+
+
+/**
+ * optional string scope = 12;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getScope = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 12, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setScope = function(value) {
+  return jspb.Message.setProto3StringField(this, 12, value);
+};
+
+
+/**
+ * optional string domain = 13;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getDomain = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 13, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setDomain = function(value) {
+  return jspb.Message.setProto3StringField(this, 13, value);
+};
+
+
+/**
+ * optional string comment = 14;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getComment = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 14, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setComment = function(value) {
+  return jspb.Message.setProto3StringField(this, 14, value);
+};
+
+
+/**
+ * optional string logo_uri = 15;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getLogoUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 15, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setLogoUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 15, value);
+};
+
+
+/**
+ * optional string application_type = 16;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getApplicationType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 16, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setApplicationType = function(value) {
+  return jspb.Message.setProto3StringField(this, 16, value);
+};
+
+
+/**
+ * optional string jwks_uri = 17;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getJwksUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 17, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setJwksUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 17, value);
+};
+
+
+/**
+ * optional string example_extension_parameter = 18;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getExampleExtensionParameter = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 18, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setExampleExtensionParameter = function(value) {
+  return jspb.Message.setProto3StringField(this, 18, value);
+};
+
+
+/**
+ * optional string tos_uri = 19;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getTosUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 19, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setTosUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 19, value);
+};
+
+
+/**
+ * optional string policy_uri = 20;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getPolicyUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 20, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setPolicyUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 20, value);
+};
+
+
+/**
+ * map<string, string> jwks = 21;
+ * @param {boolean=} opt_noLazyCreate Do not create the map if
+ * empty, instead returning `undefined`
+ * @return {!jspb.Map<string,string>}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getJwksMap = function(opt_noLazyCreate) {
+  return /** @type {!jspb.Map<string,string>} */ (
+      jspb.Message.getMapField(this, 21, opt_noLazyCreate,
+      null));
+};
+
+
+/**
+ * Clears values from the map. The map will be non-null.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.clearJwksMap = function() {
+  this.getJwksMap().clear();
+  return this;};
+
+
+/**
+ * optional string software_id = 22;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getSoftwareId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 22, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setSoftwareId = function(value) {
+  return jspb.Message.setProto3StringField(this, 22, value);
+};
+
+
+/**
+ * optional string software_version = 23;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.getSoftwareVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 23, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantResponse.prototype.setSoftwareVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 23, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.management.service.GetTenantRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    tenant: (f = msg.getTenant()) && TenantProfileService_pb.Tenant.toObject(includeInstance, f),
+    credentials: (f = msg.getCredentials()) && proto.org.apache.custos.tenant.management.service.Credentials.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantRequest}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.management.service.GetTenantRequest;
+  return proto.org.apache.custos.tenant.management.service.GetTenantRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantRequest}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 4:
+      var value = new TenantProfileService_pb.Tenant;
+      reader.readMessage(value,TenantProfileService_pb.Tenant.deserializeBinaryFromReader);
+      msg.setTenant(value);
+      break;
+    case 5:
+      var value = new proto.org.apache.custos.tenant.management.service.Credentials;
+      reader.readMessage(value,proto.org.apache.custos.tenant.management.service.Credentials.deserializeBinaryFromReader);
+      msg.setCredentials(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.management.service.GetTenantRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getTenant();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      TenantProfileService_pb.Tenant.serializeBinaryToWriter
+    );
+  }
+  f = message.getCredentials();
+  if (f != null) {
+    writer.writeMessage(
+      5,
+      f,
+      proto.org.apache.custos.tenant.management.service.Credentials.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional org.apache.custos.tenant.profile.service.Tenant tenant = 4;
+ * @return {?proto.org.apache.custos.tenant.profile.service.Tenant}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.getTenant = function() {
+  return /** @type{?proto.org.apache.custos.tenant.profile.service.Tenant} */ (
+    jspb.Message.getWrapperField(this, TenantProfileService_pb.Tenant, 4));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.tenant.profile.service.Tenant|undefined} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} returns this
+*/
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.setTenant = function(value) {
+  return jspb.Message.setWrapperField(this, 4, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.clearTenant = function() {
+  return this.setTenant(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.hasTenant = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional Credentials credentials = 5;
+ * @return {?proto.org.apache.custos.tenant.management.service.Credentials}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.getCredentials = function() {
+  return /** @type{?proto.org.apache.custos.tenant.management.service.Credentials} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.tenant.management.service.Credentials, 5));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.tenant.management.service.Credentials|undefined} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} returns this
+*/
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.setCredentials = function(value) {
+  return jspb.Message.setWrapperField(this, 5, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.clearCredentials = function() {
+  return this.setCredentials(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.management.service.GetTenantRequest.prototype.hasCredentials = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.management.service.Credentials.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.management.service.Credentials} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    iamClientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    iamClientSecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    ciLogonClientId: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    ciLogonClientSecret: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    custosClientId: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    custosClientSecret: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    custosClientIdIssuedAt: jspb.Message.getFloatingPointFieldWithDefault(msg, 7, 0.0),
+    custosClientSecretExpiredAt: jspb.Message.getFloatingPointFieldWithDefault(msg, 8, 0.0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.management.service.Credentials;
+  return proto.org.apache.custos.tenant.management.service.Credentials.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.management.service.Credentials} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamClientSecret(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCiLogonClientId(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCiLogonClientSecret(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCustosClientId(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCustosClientSecret(value);
+      break;
+    case 7:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setCustosClientIdIssuedAt(value);
+      break;
+    case 8:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setCustosClientSecretExpiredAt(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.management.service.Credentials.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.management.service.Credentials} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getIamClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getIamClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getCiLogonClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getCiLogonClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getCustosClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getCustosClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getCustosClientIdIssuedAt();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      7,
+      f
+    );
+  }
+  f = message.getCustosClientSecretExpiredAt();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string iam_client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.getIamClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials} returns this
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.setIamClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string iam_client_secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.getIamClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials} returns this
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.setIamClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string ci_logon_client_id = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.getCiLogonClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials} returns this
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.setCiLogonClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string ci_logon_client_secret = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.getCiLogonClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials} returns this
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.setCiLogonClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string custos_client_id = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.getCustosClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials} returns this
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.setCustosClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string custos_client_secret = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.getCustosClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials} returns this
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.setCustosClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional double custos_client_id_issued_at = 7;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.getCustosClientIdIssuedAt = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 7, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials} returns this
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.setCustosClientIdIssuedAt = function(value) {
+  return jspb.Message.setProto3FloatField(this, 7, value);
+};
+
+
+/**
+ * optional double custos_client_secret_expired_at = 8;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.getCustosClientSecretExpiredAt = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 8, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.management.service.Credentials} returns this
+ */
+proto.org.apache.custos.tenant.management.service.Credentials.prototype.setCustosClientSecretExpiredAt = function(value) {
+  return jspb.Message.setProto3FloatField(this, 8, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    credentials: (f = msg.getCredentials()) && proto.org.apache.custos.tenant.management.service.Credentials.toObject(includeInstance, f),
+    body: (f = msg.getBody()) && TenantProfileService_pb.Tenant.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.management.service.UpdateTenantRequest;
+  return proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 3:
+      var value = new proto.org.apache.custos.tenant.management.service.Credentials;
+      reader.readMessage(value,proto.org.apache.custos.tenant.management.service.Credentials.deserializeBinaryFromReader);
+      msg.setCredentials(value);
+      break;
+    case 4:
+      var value = new TenantProfileService_pb.Tenant;
+      reader.readMessage(value,TenantProfileService_pb.Tenant.deserializeBinaryFromReader);
+      msg.setBody(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getCredentials();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.org.apache.custos.tenant.management.service.Credentials.serializeBinaryToWriter
+    );
+  }
+  f = message.getBody();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      TenantProfileService_pb.Tenant.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional Credentials credentials = 3;
+ * @return {?proto.org.apache.custos.tenant.management.service.Credentials}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.getCredentials = function() {
+  return /** @type{?proto.org.apache.custos.tenant.management.service.Credentials} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.tenant.management.service.Credentials, 3));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.tenant.management.service.Credentials|undefined} value
+ * @return {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} returns this
+*/
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.setCredentials = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.clearCredentials = function() {
+  return this.setCredentials(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.hasCredentials = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional org.apache.custos.tenant.profile.service.Tenant body = 4;
+ * @return {?proto.org.apache.custos.tenant.profile.service.Tenant}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.getBody = function() {
+  return /** @type{?proto.org.apache.custos.tenant.profile.service.Tenant} */ (
+    jspb.Message.getWrapperField(this, TenantProfileService_pb.Tenant, 4));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.tenant.profile.service.Tenant|undefined} value
+ * @return {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} returns this
+*/
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.setBody = function(value) {
+  return jspb.Message.setWrapperField(this, 4, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.tenant.management.service.UpdateTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.clearBody = function() {
+  return this.setBody(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.management.service.UpdateTenantRequest.prototype.hasBody = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    credentials: (f = msg.getCredentials()) && proto.org.apache.custos.tenant.management.service.Credentials.toObject(includeInstance, f),
+    body: (f = msg.getBody()) && TenantProfileService_pb.Tenant.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.management.service.DeleteTenantRequest;
+  return proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 3:
+      var value = new proto.org.apache.custos.tenant.management.service.Credentials;
+      reader.readMessage(value,proto.org.apache.custos.tenant.management.service.Credentials.deserializeBinaryFromReader);
+      msg.setCredentials(value);
+      break;
+    case 4:
+      var value = new TenantProfileService_pb.Tenant;
+      reader.readMessage(value,TenantProfileService_pb.Tenant.deserializeBinaryFromReader);
+      msg.setBody(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getCredentials();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.org.apache.custos.tenant.management.service.Credentials.serializeBinaryToWriter
+    );
+  }
+  f = message.getBody();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      TenantProfileService_pb.Tenant.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional Credentials credentials = 3;
+ * @return {?proto.org.apache.custos.tenant.management.service.Credentials}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.getCredentials = function() {
+  return /** @type{?proto.org.apache.custos.tenant.management.service.Credentials} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.tenant.management.service.Credentials, 3));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.tenant.management.service.Credentials|undefined} value
+ * @return {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} returns this
+*/
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.setCredentials = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.clearCredentials = function() {
+  return this.setCredentials(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.hasCredentials = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional org.apache.custos.tenant.profile.service.Tenant body = 4;
+ * @return {?proto.org.apache.custos.tenant.profile.service.Tenant}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.getBody = function() {
+  return /** @type{?proto.org.apache.custos.tenant.profile.service.Tenant} */ (
+    jspb.Message.getWrapperField(this, TenantProfileService_pb.Tenant, 4));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.tenant.profile.service.Tenant|undefined} value
+ * @return {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} returns this
+*/
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.setBody = function(value) {
+  return jspb.Message.setWrapperField(this, 4, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.tenant.management.service.DeleteTenantRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.clearBody = function() {
+  return this.setBody(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.tenant.management.service.DeleteTenantRequest.prototype.hasBody = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.management.service.GetCredentialsRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetCredentialsRequest}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.management.service.GetCredentialsRequest;
+  return proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.management.service.GetCredentialsRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetCredentialsRequest}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.management.service.GetCredentialsRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetCredentialsRequest} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.tenant.management.service.GetCredentialsResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    iamclientid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    iamclientsecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    cilogonclientid: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    cilogonclientsecret: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetCredentialsResponse}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.tenant.management.service.GetCredentialsResponse;
+  return proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.tenant.management.service.GetCredentialsResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.tenant.management.service.GetCredentialsResponse}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientsecret(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCilogonclientid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCilogonclientsecret(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.tenant.management.service.GetCredentialsResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getIamclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getIamclientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getCilogonclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getCilogonclientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string iamClientId = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.getIamclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetCredentialsResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.setIamclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string iamClientSecret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.getIamclientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetCredentialsResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.setIamclientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string ciLogonClientId = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.getCilogonclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetCredentialsResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.setCilogonclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string ciLogonClientSecret = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.getCilogonclientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.tenant.management.service.GetCredentialsResponse} returns this
+ */
+proto.org.apache.custos.tenant.management.service.GetCredentialsResponse.prototype.setCilogonclientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+goog.object.extend(exports, proto.org.apache.custos.tenant.management.service);
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/user-management/UserManagementService_grpc_web_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/user-management/UserManagementService_grpc_web_pb.js
new file mode 100644
index 0000000..194ccef
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/user-management/UserManagementService_grpc_web_pb.js
@@ -0,0 +1,1942 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+/**
+ * @fileoverview gRPC-Web generated client stub for org.apache.custos.user.management.service
+ * @enhanceable
+ * @public
+ */
+
+// GENERATED CODE -- DO NOT EDIT!
+
+
+/* eslint-disable */
+// @ts-nocheck
+
+
+
+const grpc = {};
+grpc.web = require('grpc-web');
+
+
+var UserProfileService_pb = require('../../core-services/user-profile/UserProfileService_pb.js')
+
+var IamAdminService_pb = require('../../core-services/iam-admin-service/IamAdminService_pb.js')
+const proto = {};
+proto.org = {};
+proto.org.apache = {};
+proto.org.apache.custos = {};
+proto.org.apache.custos.user = {};
+proto.org.apache.custos.user.management = {};
+proto.org.apache.custos.user.management.service = require('./UserManagementService_pb.js');
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.RegisterUserRequest,
+ *   !proto.org.apache.custos.iam.service.RegisterUserResponse>}
+ */
+const methodDescriptor_UserManagementService_registerUser = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/registerUser',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.RegisterUserRequest,
+  IamAdminService_pb.RegisterUserResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.RegisterUserResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.RegisterUserRequest,
+ *   !proto.org.apache.custos.iam.service.RegisterUserResponse>}
+ */
+const methodInfo_UserManagementService_registerUser = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.RegisterUserResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.RegisterUserResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.RegisterUserResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.RegisterUserResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.registerUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/registerUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_registerUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.RegisterUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.RegisterUserResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.registerUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/registerUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_registerUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.RegisterUsersRequest,
+ *   !proto.org.apache.custos.iam.service.RegisterUsersResponse>}
+ */
+const methodDescriptor_UserManagementService_registerAndEnableUsers = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/registerAndEnableUsers',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.RegisterUsersRequest,
+  IamAdminService_pb.RegisterUsersResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.RegisterUsersRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.RegisterUsersResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.RegisterUsersRequest,
+ *   !proto.org.apache.custos.iam.service.RegisterUsersResponse>}
+ */
+const methodInfo_UserManagementService_registerAndEnableUsers = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.RegisterUsersResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.RegisterUsersRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.RegisterUsersResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.RegisterUsersRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.RegisterUsersResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.RegisterUsersResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.registerAndEnableUsers =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/registerAndEnableUsers',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_registerAndEnableUsers,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.RegisterUsersRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.RegisterUsersResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.registerAndEnableUsers =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/registerAndEnableUsers',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_registerAndEnableUsers);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.AddUserAttributesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_addUserAttributes = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/addUserAttributes',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.AddUserAttributesRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.AddUserAttributesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_addUserAttributes = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.addUserAttributes =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/addUserAttributes',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_addUserAttributes,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddUserAttributesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.addUserAttributes =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/addUserAttributes',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_addUserAttributes);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.DeleteUserAttributeRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_deleteUserAttributes = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/deleteUserAttributes',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.DeleteUserAttributeRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.DeleteUserAttributeRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_deleteUserAttributes = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.deleteUserAttributes =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/deleteUserAttributes',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_deleteUserAttributes,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserAttributeRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.deleteUserAttributes =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/deleteUserAttributes',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_deleteUserAttributes);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+const methodDescriptor_UserManagementService_enableUser = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/enableUser',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserSearchRequest,
+  IamAdminService_pb.UserRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.UserRepresentation.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+const methodInfo_UserManagementService_enableUser = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.UserRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.UserRepresentation.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.UserRepresentation)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.UserRepresentation>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.enableUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/enableUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_enableUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.UserRepresentation>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.enableUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/enableUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_enableUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+const methodDescriptor_UserManagementService_disableUser = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/disableUser',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserSearchRequest,
+  IamAdminService_pb.UserRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.UserRepresentation.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+const methodInfo_UserManagementService_disableUser = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.UserRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.UserRepresentation.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.UserRepresentation)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.UserRepresentation>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.disableUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/disableUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_disableUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.UserRepresentation>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.disableUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/disableUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_disableUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_grantAdminPrivileges = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/grantAdminPrivileges',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserSearchRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_grantAdminPrivileges = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.grantAdminPrivileges =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/grantAdminPrivileges',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_grantAdminPrivileges,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.grantAdminPrivileges =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/grantAdminPrivileges',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_grantAdminPrivileges);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_removeAdminPrivileges = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/removeAdminPrivileges',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserSearchRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_removeAdminPrivileges = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.removeAdminPrivileges =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/removeAdminPrivileges',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_removeAdminPrivileges,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.removeAdminPrivileges =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/removeAdminPrivileges',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_removeAdminPrivileges);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.AddUserRolesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_addRolesToUsers = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/addRolesToUsers',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.AddUserRolesRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.AddUserRolesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_addRolesToUsers = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.addRolesToUsers =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/addRolesToUsers',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_addRolesToUsers,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.AddUserRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.addRolesToUsers =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/addRolesToUsers',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_addRolesToUsers);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_isUserEnabled = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/isUserEnabled',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserSearchRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_isUserEnabled = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.isUserEnabled =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/isUserEnabled',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_isUserEnabled,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.isUserEnabled =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/isUserEnabled',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_isUserEnabled);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_isUsernameAvailable = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/isUsernameAvailable',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserSearchRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_isUsernameAvailable = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.isUsernameAvailable =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/isUsernameAvailable',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_isUsernameAvailable,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.isUsernameAvailable =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/isUsernameAvailable',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_isUsernameAvailable);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+const methodDescriptor_UserManagementService_getUser = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/getUser',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserSearchRequest,
+  IamAdminService_pb.UserRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.UserRepresentation.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.UserRepresentation>}
+ */
+const methodInfo_UserManagementService_getUser = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.UserRepresentation,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.UserRepresentation.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.UserRepresentation)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.UserRepresentation>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.getUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/getUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_getUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.UserRepresentation>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.getUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/getUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_getUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.FindUsersRequest,
+ *   !proto.org.apache.custos.iam.service.FindUsersResponse>}
+ */
+const methodDescriptor_UserManagementService_findUsers = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/findUsers',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.FindUsersRequest,
+  IamAdminService_pb.FindUsersResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.FindUsersRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.FindUsersResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.FindUsersRequest,
+ *   !proto.org.apache.custos.iam.service.FindUsersResponse>}
+ */
+const methodInfo_UserManagementService_findUsers = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.FindUsersResponse,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.FindUsersRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.FindUsersResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.FindUsersRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.FindUsersResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.FindUsersResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.findUsers =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/findUsers',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_findUsers,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.FindUsersRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.FindUsersResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.findUsers =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/findUsers',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_findUsers);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.ResetUserPassword,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_resetPassword = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/resetPassword',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.ResetUserPassword,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.ResetUserPassword} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.ResetUserPassword,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_resetPassword = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.ResetUserPassword} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.ResetUserPassword} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.resetPassword =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/resetPassword',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_resetPassword,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.ResetUserPassword} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.resetPassword =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/resetPassword',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_resetPassword);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_deleteUser = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/deleteUser',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.UserSearchRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.UserSearchRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_deleteUser = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.deleteUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/deleteUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_deleteUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.UserSearchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.deleteUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/deleteUser',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_deleteUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.iam.service.DeleteUserRolesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_deleteUserRoles = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/deleteUserRoles',
+  grpc.web.MethodType.UNARY,
+  IamAdminService_pb.DeleteUserRolesRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.iam.service.DeleteUserRolesRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_deleteUserRoles = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.deleteUserRoles =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/deleteUserRoles',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_deleteUserRoles,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.iam.service.DeleteUserRolesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.deleteUserRoles =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/deleteUserRoles',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_deleteUserRoles);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.management.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.UserProfile>}
+ */
+const methodDescriptor_UserManagementService_updateUserProfile = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/updateUserProfile',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.user.management.service.UserProfileRequest,
+  UserProfileService_pb.UserProfile,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.UserProfile.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.management.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.UserProfile>}
+ */
+const methodInfo_UserManagementService_updateUserProfile = new grpc.web.AbstractClientBase.MethodInfo(
+  UserProfileService_pb.UserProfile,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.UserProfile.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.user.profile.service.UserProfile)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.user.profile.service.UserProfile>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.updateUserProfile =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/updateUserProfile',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_updateUserProfile,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.user.profile.service.UserProfile>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.updateUserProfile =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/updateUserProfile',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_updateUserProfile);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.management.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.UserProfile>}
+ */
+const methodDescriptor_UserManagementService_getUserProfile = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/getUserProfile',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.user.management.service.UserProfileRequest,
+  UserProfileService_pb.UserProfile,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.UserProfile.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.management.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.UserProfile>}
+ */
+const methodInfo_UserManagementService_getUserProfile = new grpc.web.AbstractClientBase.MethodInfo(
+  UserProfileService_pb.UserProfile,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.UserProfile.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.user.profile.service.UserProfile)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.user.profile.service.UserProfile>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.getUserProfile =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/getUserProfile',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_getUserProfile,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.user.profile.service.UserProfile>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.getUserProfile =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/getUserProfile',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_getUserProfile);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.management.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.UserProfile>}
+ */
+const methodDescriptor_UserManagementService_deleteUserProfile = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/deleteUserProfile',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.user.management.service.UserProfileRequest,
+  UserProfileService_pb.UserProfile,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.UserProfile.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.management.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.UserProfile>}
+ */
+const methodInfo_UserManagementService_deleteUserProfile = new grpc.web.AbstractClientBase.MethodInfo(
+  UserProfileService_pb.UserProfile,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.UserProfile.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.user.profile.service.UserProfile)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.user.profile.service.UserProfile>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.deleteUserProfile =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/deleteUserProfile',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_deleteUserProfile,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.user.profile.service.UserProfile>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.deleteUserProfile =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/deleteUserProfile',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_deleteUserProfile);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.management.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse>}
+ */
+const methodDescriptor_UserManagementService_getAllUserProfilesInTenant = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/getAllUserProfilesInTenant',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.user.management.service.UserProfileRequest,
+  UserProfileService_pb.GetAllUserProfilesResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllUserProfilesResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.management.service.UserProfileRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse>}
+ */
+const methodInfo_UserManagementService_getAllUserProfilesInTenant = new grpc.web.AbstractClientBase.MethodInfo(
+  UserProfileService_pb.GetAllUserProfilesResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetAllUserProfilesResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.getAllUserProfilesInTenant =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/getAllUserProfilesInTenant',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_getAllUserProfilesInTenant,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.user.profile.service.GetAllUserProfilesResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.getAllUserProfilesInTenant =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/getAllUserProfilesInTenant',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_getAllUserProfilesInTenant);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.management.service.LinkUserProfileRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_linkUserProfile = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/linkUserProfile',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.user.management.service.LinkUserProfileRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.management.service.LinkUserProfileRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_linkUserProfile = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.linkUserProfile =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/linkUserProfile',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_linkUserProfile,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.linkUserProfile =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/linkUserProfile',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_linkUserProfile);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse>}
+ */
+const methodDescriptor_UserManagementService_getUserProfileAuditTrails = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/getUserProfileAuditTrails',
+  grpc.web.MethodType.UNARY,
+  UserProfileService_pb.GetUpdateAuditTrailRequest,
+  UserProfileService_pb.GetUpdateAuditTrailResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetUpdateAuditTrailResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest,
+ *   !proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse>}
+ */
+const methodInfo_UserManagementService_getUserProfileAuditTrails = new grpc.web.AbstractClientBase.MethodInfo(
+  UserProfileService_pb.GetUpdateAuditTrailResponse,
+  /**
+   * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  UserProfileService_pb.GetUpdateAuditTrailResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.getUserProfileAuditTrails =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/getUserProfileAuditTrails',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_getUserProfileAuditTrails,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.getUserProfileAuditTrails =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/getUserProfileAuditTrails',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_getUserProfileAuditTrails);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodDescriptor_UserManagementService_synchronizeUserDBs = new grpc.web.MethodDescriptor(
+  '/org.apache.custos.user.management.service.UserManagementService/synchronizeUserDBs',
+  grpc.web.MethodType.UNARY,
+  proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest,
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest,
+ *   !proto.org.apache.custos.iam.service.OperationStatus>}
+ */
+const methodInfo_UserManagementService_synchronizeUserDBs = new grpc.web.AbstractClientBase.MethodInfo(
+  IamAdminService_pb.OperationStatus,
+  /**
+   * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  IamAdminService_pb.OperationStatus.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.org.apache.custos.iam.service.OperationStatus)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.org.apache.custos.iam.service.OperationStatus>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.org.apache.custos.user.management.service.UserManagementServiceClient.prototype.synchronizeUserDBs =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/synchronizeUserDBs',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_synchronizeUserDBs,
+      callback);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.org.apache.custos.iam.service.OperationStatus>}
+ *     A native promise that resolves to the response
+ */
+proto.org.apache.custos.user.management.service.UserManagementServicePromiseClient.prototype.synchronizeUserDBs =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/org.apache.custos.user.management.service.UserManagementService/synchronizeUserDBs',
+      request,
+      metadata || {},
+      methodDescriptor_UserManagementService_synchronizeUserDBs);
+};
+
+
+module.exports = proto.org.apache.custos.user.management.service;
+
diff --git a/custos-client-sdks/custos-js-sdk/stubs/integration-services/user-management/UserManagementService_pb.js b/custos-client-sdks/custos-js-sdk/stubs/integration-services/user-management/UserManagementService_pb.js
new file mode 100644
index 0000000..ef705ab
--- /dev/null
+++ b/custos-client-sdks/custos-js-sdk/stubs/integration-services/user-management/UserManagementService_pb.js
@@ -0,0 +1,1954 @@
+// source: src/main/proto/UserManagementService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+var google_api_annotations_pb = require('../../../google/api/annotations_pb.js');
+goog.object.extend(proto, google_api_annotations_pb);
+var UserProfileService_pb = require('../../../UserProfileService_pb.js');
+goog.object.extend(proto, UserProfileService_pb);
+var IamAdminService_pb = require('../../../IamAdminService_pb.js');
+goog.object.extend(proto, IamAdminService_pb);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.GetUserRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.GetUsersRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.LinkUserProfileRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.ResetPassword', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.ResetPasswordRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.UserProfileRequest', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.UserProfileRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.UserProfileRequest.displayName = 'proto.org.apache.custos.user.management.service.UserProfileRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.GetUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.GetUserRequest.displayName = 'proto.org.apache.custos.user.management.service.GetUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.GetUsersRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.GetUsersRequest.displayName = 'proto.org.apache.custos.user.management.service.GetUsersRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.ResetPassword = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.ResetPassword, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.ResetPassword.displayName = 'proto.org.apache.custos.user.management.service.ResetPassword';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.ResetPasswordRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.ResetPasswordRequest.displayName = 'proto.org.apache.custos.user.management.service.ResetPasswordRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.user.management.service.LinkUserProfileRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.LinkUserProfileRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.LinkUserProfileRequest.displayName = 'proto.org.apache.custos.user.management.service.LinkUserProfileRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.displayName = 'proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.UserProfileRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    userProfile: (f = msg.getUserProfile()) && UserProfileService_pb.UserProfile.toObject(includeInstance, f),
+    clientid: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.UserProfileRequest;
+  return proto.org.apache.custos.user.management.service.UserProfileRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new UserProfileService_pb.UserProfile;
+      reader.readMessage(value,UserProfileService_pb.UserProfile.deserializeBinaryFromReader);
+      msg.setUserProfile(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.UserProfileRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUserProfile();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      UserProfileService_pb.UserProfile.serializeBinaryToWriter
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional org.apache.custos.user.profile.service.UserProfile user_profile = 1;
+ * @return {?proto.org.apache.custos.user.profile.service.UserProfile}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getUserProfile = function() {
+  return /** @type{?proto.org.apache.custos.user.profile.service.UserProfile} */ (
+    jspb.Message.getWrapperField(this, UserProfileService_pb.UserProfile, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.user.profile.service.UserProfile|undefined} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+*/
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setUserProfile = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.clearUserProfile = function() {
+  return this.setUserProfile(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.hasUserProfile = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string clientId = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenantId = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string accessToken = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string clientSecret = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string performedBy = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.GetUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.GetUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    username: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    usersearchrequest: (f = msg.getUsersearchrequest()) && IamAdminService_pb.UserSearchRequest.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.GetUserRequest;
+  return proto.org.apache.custos.user.management.service.GetUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.GetUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 2:
+      var value = new IamAdminService_pb.UserSearchRequest;
+      reader.readMessage(value,IamAdminService_pb.UserSearchRequest.deserializeBinaryFromReader);
+      msg.setUsersearchrequest(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.GetUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.GetUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getUsersearchrequest();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      IamAdminService_pb.UserSearchRequest.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string username = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional org.apache.custos.iam.service.UserSearchRequest userSearchRequest = 2;
+ * @return {?proto.org.apache.custos.iam.service.UserSearchRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.getUsersearchrequest = function() {
+  return /** @type{?proto.org.apache.custos.iam.service.UserSearchRequest} */ (
+    jspb.Message.getWrapperField(this, IamAdminService_pb.UserSearchRequest, 2));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.iam.service.UserSearchRequest|undefined} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest} returns this
+*/
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.setUsersearchrequest = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.clearUsersearchrequest = function() {
+  return this.setUsersearchrequest(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.hasUsersearchrequest = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.GetUsersRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.GetUsersRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    email: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    offset: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    limit: jspb.Message.getFieldWithDefault(msg, 5, 0),
+    search: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    iamclientid: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    iamclientsecret: jspb.Message.getFieldWithDefault(msg, 8, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.GetUsersRequest;
+  return proto.org.apache.custos.user.management.service.GetUsersRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.GetUsersRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEmail(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setOffset(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setLimit(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSearch(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientid(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientsecret(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.GetUsersRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.GetUsersRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getOffset();
+  if (f !== 0) {
+    writer.writeInt32(
+      4,
+      f
+    );
+  }
+  f = message.getLimit();
+  if (f !== 0) {
+    writer.writeInt32(
+      5,
+      f
+    );
+  }
+  f = message.getSearch();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getIamclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getIamclientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string email = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string username = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional int32 offset = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getOffset = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setOffset = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional int32 limit = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getLimit = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setLimit = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+/**
+ * optional string search = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getSearch = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setSearch = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string iamClientId = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getIamclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setIamclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string iamClientSecret = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getIamclientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setIamclientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.ResetPassword.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.ResetPassword} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    password: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    iamclientid: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    iamclientsecret: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.ResetPassword;
+  return proto.org.apache.custos.user.management.service.ResetPassword.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.ResetPassword} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientid(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientsecret(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.ResetPassword.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.ResetPassword} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getIamclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getIamclientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string accessToken = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string username = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string password = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string iamClientId = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getIamclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setIamclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string iamClientSecret = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getIamclientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setIamclientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.ResetPasswordRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    passwordmetadata: (f = msg.getPasswordmetadata()) && proto.org.apache.custos.user.management.service.ResetPassword.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPasswordRequest}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.ResetPasswordRequest;
+  return proto.org.apache.custos.user.management.service.ResetPasswordRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPasswordRequest}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.user.management.service.ResetPassword;
+      reader.readMessage(value,proto.org.apache.custos.user.management.service.ResetPassword.deserializeBinaryFromReader);
+      msg.setPasswordmetadata(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.ResetPasswordRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getPasswordmetadata();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.org.apache.custos.user.management.service.ResetPassword.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional ResetPassword passwordMetadata = 1;
+ * @return {?proto.org.apache.custos.user.management.service.ResetPassword}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.getPasswordmetadata = function() {
+  return /** @type{?proto.org.apache.custos.user.management.service.ResetPassword} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.user.management.service.ResetPassword, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.user.management.service.ResetPassword|undefined} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} returns this
+*/
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.setPasswordmetadata = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.clearPasswordmetadata = function() {
+  return this.setPasswordmetadata(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.hasPasswordmetadata = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.repeatedFields_ = [3];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.LinkUserProfileRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    currentUsername: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    previousUsername: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    linkingAttributesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    tenantid: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    iamclientid: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    iamclientsecret: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 8, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.LinkUserProfileRequest;
+  return proto.org.apache.custos.user.management.service.LinkUserProfileRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCurrentUsername(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPreviousUsername(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addLinkingAttributes(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientid(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientsecret(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.LinkUserProfileRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getCurrentUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getPreviousUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getLinkingAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+  f = message.getIamclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getIamclientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string current_username = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getCurrentUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setCurrentUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string previous_username = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getPreviousUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setPreviousUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string linking_attributes = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getLinkingAttributesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setLinkingAttributesList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.addLinkingAttributes = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.clearLinkingAttributesList = function() {
+  return this.setLinkingAttributesList([]);
+};
+
+
+/**
+ * optional int64 tenantId = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional string iamClientId = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getIamclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setIamclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string iamClientSecret = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getIamclientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setIamclientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string accessToken = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string performedBy = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    clientid: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest;
+  return proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional string clientId = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+goog.object.extend(exports, proto.org.apache.custos.user.management.service);
diff --git a/custos-client-sdks/custos-python-sdk/.gitignore b/custos-client-sdks/custos-python-sdk/.gitignore
new file mode 100644
index 0000000..9d29e4a
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/.gitignore
@@ -0,0 +1,3 @@
+venv
+*.pyc
+.tox
\ No newline at end of file
diff --git a/custos-client-sdks/custos-python-sdk/LICENSE b/custos-client-sdks/custos-python-sdk/LICENSE
new file mode 100644
index 0000000..f49a4e1
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
\ No newline at end of file
diff --git a/custos-client-sdks/custos-python-sdk/README.md b/custos-client-sdks/custos-python-sdk/README.md
new file mode 100644
index 0000000..3e3ed7f
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/README.md
@@ -0,0 +1,154 @@
+# Apache Custos Python SDK
+The Apache Custos Python SDK for  third party clients to  integrate with Custos middleware
+
+
+### Folder Structure
+
+ - custos
+      
+    Includes gRPC stubs generated by a protoc compiler. Mainly contains data model and functions. You may 
+              need to import data model packages to integrate with clients. 
+              
+ - clients
+      
+     Includes integration clients, which you want to import and integrate with your code to access Custos middleware.
+              
+ - samples
+      
+   Includes set of sample implementation of  integration clients to demo the integration with  Custos middleware
+              
+ - transport
+ 
+   Includes connection handling classes 
+              
+
+### Before  Integration
+
+  -  Create a virtual environment
+                
+       ```
+       python3 -m venv venv
+        ```    
+  -  Activate the virtual environment
+        
+       ```
+       source venv/bin/activate
+       ```
+  -  Install dependencies
+            
+       ```
+       pip install -r requirements.txt
+       ```
+  -  Create a INI file containing server configuration details. For more information refer to default settings file
+            
+       [settings.ini](custos/transport/settings.ini)
+       
+### Generating Distribution Archives (Optional)
+
+   You can generate *.tar.gz or .whl distribution and install to any external project. 
+   
+   -  Create a virtual environment
+                
+       ```
+       python3 -m venv venv
+        ```    
+   -  Activate the virtual environment
+        
+       ```
+       source venv/bin/activate
+       ```
+   - Make sure you have the latest versions of setuptools and wheel installed
+    
+       ```
+       pip install  wheel
+       ``` 
+     
+   - Now run this command from the same directory where setup.py is located
+   
+        ```
+        python3 setup.py sdist bdist_wheel
+        ```
+   - This command should output a lot of text and once completed should generate two files in the dist directory
+   
+        ```
+        dist/
+            custos_python_sdk-1.0.0-py3-none-any.whl
+            custos-python-sdk-1.0.0.tar.gz
+        ```     
+
+You should be able to install those packages into your project.
+
+
+
+### Integrate With Your Clients
+
+There are three types of tokens used for access custos APIs.
+   
+   - Client Token (Base64 encoded Custos_Client_Id +":"+ Custos_Client_Sec)
+   - Admin Token (Access Token of Admin User)
+   - User Token (Access Token of Generic User)
+      
+   -  [tenant_management_client](custos/clients/tenant_management_client.py)
+   
+      - create_admin_tenant (<sub><sup>client_name, requester_email, admin_frist_name,
+                            admin_last_name, admin_email, admin_username, admin_password,
+                            contacts, redirect_uris, client_uri, scope, domain, logo_uri, comment</sup></sub>)
+      - create_tenant (<sub><sup>client_token, client_name, requester_email, admin_frist_name,
+                            admin_last_name, admin_email, admin_username, admin_password,
+                            contacts, redirect_uris, client_uri, scope, domain, logo_uri, comment</sup></sub>)
+      - get_credentials (<sub><sup>client_token</sup></sub>)
+      - get_tenant (<sub><sup>client_token, client_id</sup></sub>)
+      - update_tenant (<sub><sup>client_token, client_id, client_name, requester_email, admin_frist_name,
+                      admin_last_name, admin_email, admin_username, admin_password,
+                      contacts, redirect_uris, client_uri, scope, domain, logo_uri, comment</sup></sub>)
+      - delete_tenant (<sub><sup>client_token, client_id</sup></sub>)
+      - add_tenant_roles (<sub><sup>client_token, roles, is_client_level</sup></sub>)
+      - add_protocol_mapper (<sub><sup>client_token, roles, is_client_level</sup></sub>)
+      - get_child_tenants (<sub><sup> client_token, offset, limit, status</sup></sub>)
+      - get_all_tenants (<sub><sup> client_token, email</sup></sub>)
+      
+    
+      
+   Sample implementations can be found at [tenant_management_samples](custos/samples/tenant_management_samples.py)
+      
+   -   [identity_management_client](custos/clients/identity_management_client.py)
+      
+       - authenticate(<sub><sup>client_token, username, password</sup></sub>)
+       - is_authenticated(<sub><sup> client_token, user_access_token, username</sup></sub>)
+       - get_service_account_access_token(<sub><sup> client_token</sup></sub>)
+       - authorize(<sub><sup> client_id, redirect_uri, response_type, scope, state</sup></sub>)
+       - token(<sub><sup>  client_token, redirect_uri, code</sup></sub>)
+       - get_credentials(<sub><sup>  client_token, client_id</sup></sub>)
+       - get_oidc_configuration(<sub><sup> client_token, client_id</sup></sub>)
+       
+   Sample implementations can be found at [identity_management_sample](custos/samples/identity_management_samples.py)
+    
+    
+   - [user_management_client](custos/clients/user_management_client.py)   
+       
+       - register_user(<sub><sup>client_token, username, first_name, last_name, password, email, is_temp_password</sup></sub>) 
+       - register_and_enable_users(<sub><sup> admin_token, users</sup></sub>)
+       - add_user_attributes(<sub><sup> user_token, attributes, users</sup></sub>)
+       - delete_user_attributes(<sub><sup> user_token, attributes, users</sup></sub>)
+       - enable_user(<sub><sup> client_token, username</sup></sub>)
+       - add_roles_to_users(<sub><sup> admin_token, usernames, roles, is_client_level</sup></sub>)
+       - is_user_enabled(<sub><sup>  client_token, username</sup></sub>)
+       - is_username_available(<sub><sup> client_token, username</sup></sub>)
+       - get_user(<sub><sup> client_token, username</sup></sub>)
+       - find_users(<sub><sup> client_token, offset, limit, username=None, firstname=None, lastname=None, email=None</sup></sub>)
+       - reset_password(<sub><sup> client_token, username, password</sup></sub>)
+       - delete_user(<sub><sup>  admin_token, username</sup></sub>)
+       - delete_user_roles(<sub><sup> admin_token, username, client_roles, realm_roles</sup></sub>)
+       - update_user_profile(<sub><sup> user_token, username, email, first_name, last_name</sup></sub>)
+       
+       
+   Sample implementations can be found at [user_management_samples](custos/samples/user_management_sample.py)
+       
+       
+       
+   - [super_tenant_management_client](custos/clients/super_tenant_management_client.py)
+   
+       - get_all_tenants(<sub><sup> super_admin_token, offset, limit, status</sup></sub>)
+       - update_tenant_status(<sub><sup>  super_admin_token, client_id, status</sup></sub>)
+ 
+  
\ No newline at end of file
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/__init__.py
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/__init__.py
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/custos/__init__.py
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/custos/__init__.py
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/custos/clients/__init__.py
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/custos/clients/__init__.py
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/agent_management_client.py b/custos-client-sdks/custos-python-sdk/custos/clients/agent_management_client.py
new file mode 100644
index 0000000..3980b49
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/agent_management_client.py
@@ -0,0 +1,293 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+
+
+import logging
+import grpc
+
+from custos.transport.settings import CustosServerClientSettings
+
+from custos.server.integration.AgentManagementService_pb2_grpc import AgentManagementServiceStub
+from custos.server.core.IamAdminService_pb2 import AgentClientMetadata, RegisterUserRequest, \
+    UserRepresentation, UserAttribute, AddUserAttributesRequest, DeleteUserAttributeRequest, AddUserRolesRequest, \
+    DeleteUserRolesRequest, AddProtocolMapperRequest, ClaimJSONTypes, MapperTypes
+from custos.server.integration.AgentManagementService_pb2 import AgentSearchRequest
+from custos.clients.utils.certificate_fetching_rest_client import CertificateFetchingRestClient
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class AgentManagementClient(object):
+
+    def __init__(self, custos_server_setting):
+        self.custos_settings = custos_server_setting
+        self.target = self.custos_settings.CUSTOS_SERVER_HOST + ":" + str(self.custos_settings.CUSTOS_SERVER_PORT)
+        certManager = CertificateFetchingRestClient(custos_server_setting)
+        certManager.load_certificate()
+        with open(self.custos_settings.CUSTOS_CERT_PATH, 'rb') as f:
+            trusted_certs = f.read()
+        self.channel_credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
+        self.channel = grpc.secure_channel(target=self.target, credentials=self.channel_credentials)
+        self.agent_stub = AgentManagementServiceStub(self.channel)
+
+    def enable_agents(self, token):
+        """
+        Enable agent registration for realm
+        :param token:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            return self.agent_stub.enableAgents(metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while enabling agents")
+            raise
+
+    def configure_agent_client(self, token, access_token_life_time):
+        """
+        Configure agent client
+        :param token:
+        :param access_token_life_time:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = AgentClientMetadata(access_token_life_time=access_token_life_time)
+
+            return self.agent_stub.enableAgents(request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while configuring agent client")
+            raise
+
+    def register_and_enable_agent(self, token, agent):
+        """
+        Register and enable agent
+        :param agent:
+        :param token:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            attributeList = []
+            for atr in agent['attributes']:
+                attribute = UserAttribute(key=atr['key'], values=atr['values'])
+                attributeList.append(attribute)
+            id = agent['id']
+            realm_roles = agent['realm_roles']
+            user = UserRepresentation(id=id, realm_roles=realm_roles, attributes=attributeList)
+            request = RegisterUserRequest(user=user)
+
+            return self.agent_stub.registerAndEnableAgent(request=request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred while enabling agents")
+            raise
+
+    def get_agent(self, token, id):
+        """
+        Get agent having id
+        :param token:
+        :param id:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = AgentSearchRequest(id=id)
+            return self.agent_stub.getAgent(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while fetching agent")
+            raise
+
+    def delete_agent(self, token, id):
+        """
+        Delete agent having id
+        :param token:
+        :param id:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = AgentSearchRequest(id=id)
+            return self.agent_stub.deleteAgent(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while deleting agent")
+            raise
+
+    def disable_agent(self, token, id):
+        """
+        Disable agent having id
+        :param token:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = AgentSearchRequest(id=id)
+            return self.agent_stub.disableAgent(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while disabling agent")
+            raise
+
+    def enable_agent(self, token, id):
+        """
+        Enable agent having id
+        :param token:
+        :param id:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = AgentSearchRequest(id=id)
+            return self.agent_stub.enableAgent(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while enabling agent")
+            raise
+
+    def add_agent_attributes(self, token, agents, attributes):
+        """
+        Add attributes to agents
+        :param token:
+        :param agents:
+        :param attributes:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            attributeList = []
+            for atr in attributes:
+                attribute = UserAttribute(key=atr['key'], values=atr['values'])
+                attributeList.append(attribute)
+
+            request = AddUserAttributesRequest(attributes=attributeList, agents=agents)
+            return self.agent_stub.addAgentAttributes(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while adding agent attributes")
+            raise
+
+    def delete_agent_attributes(self, token, agents, attributes):
+        """
+        Delete agent attributes of agents
+        :param token:
+        :param agents:
+        :param attributes:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            attributeList = []
+            for atr in attributes:
+                attribute = UserAttribute(key=atr['key'], values=atr['values'])
+                attributeList.append(attribute)
+
+            request = DeleteUserAttributeRequest(attributes=attributeList, agents=agents)
+            return self.agent_stub.deleteAgentAttributes(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while deleting agent attributes")
+            raise
+
+    def add_roles_to_agents(self, token, agents, roles):
+        """
+        Add roles to agents
+        :param token:
+        :param agents:
+        :param roles:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            request = AddUserRolesRequest(agents=agents, roles=roles)
+            return self.agent_stub.addRolesToAgent(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred whiling adding roles to agents")
+            raise
+
+    def delete_roles_from_agent(self, token, id, roles):
+        """
+        Delete roles from agent
+        :param token:
+        :param id:
+       :param roles:
+       :return:
+       """
+
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            request = DeleteUserRolesRequest(id=id, roles=roles)
+            return self.agent_stub.deleteRolesFromAgent(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while enabling agents")
+            raise
+
+    def add_protocol_mapper(self, token, name, attribute_name, claim_name, claim_type, mapper_type,
+                            add_to_id_token, add_to_access_token, add_to_user_info, multi_valued,
+                            aggregate_attribute_values):
+        """
+        Add protocol mapper to agent client
+        :param token:
+        :param name:
+        :param attribute_name:
+        :param claim_name:
+        :param claim_type:
+        :param mapper_type:
+        :param add_to_id_token:
+        :param add_to_access_token:
+        :param add_to_user_info:
+        :param multi_valued:
+        :param aggregate_attribute_values:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            wrapped_json_type = ClaimJSONTypes.Value(claim_type)
+            wrapped_mapper_type = MapperTypes.Value(mapper_type)
+
+            request = AddProtocolMapperRequest(name=name,
+                                               attribute_name=attribute_name,
+                                               claim_name=claim_name,
+                                               claim_type=wrapped_json_type,
+                                               mapper_type=wrapped_mapper_type,
+                                               add_to_id_token=add_to_id_token,
+                                               add_to_access_token=add_to_access_token,
+                                               add_to_user_info=add_to_user_info,
+                                               multi_valued=multi_valued,
+                                               aggregate_attribute_values=aggregate_attribute_values
+                                               )
+
+            return self.agent_stub.addProtocolMapper(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in add_protocol_mapper, probably due to invalid parameters")
+            raise
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/group_management_client.py b/custos-client-sdks/custos-python-sdk/custos/clients/group_management_client.py
new file mode 100644
index 0000000..ae4cf54
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/group_management_client.py
@@ -0,0 +1,173 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+
+
+import logging
+import grpc
+
+from custos.transport.settings import CustosServerClientSettings
+
+from custos.server.integration.GroupManagementService_pb2_grpc import GroupManagementServiceStub
+from custos.server.core.IamAdminService_pb2 import GroupRequest, GroupsRequest, UserGroupMappingRequest, \
+    UserAttribute, GroupRepresentation
+
+from custos.server.core.UserProfileService_pb2 import GroupToGroupMembership
+from custos.clients.utils.certificate_fetching_rest_client import CertificateFetchingRestClient
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class GroupManagementClient(object):
+
+    def __init__(self, custos_server_setting):
+        self.custos_settings = custos_server_setting
+        self.target = self.custos_settings.CUSTOS_SERVER_HOST + ":" + str(self.custos_settings.CUSTOS_SERVER_PORT)
+        certManager = CertificateFetchingRestClient(custos_server_setting)
+        certManager.load_certificate()
+        with open(self.custos_settings.CUSTOS_CERT_PATH, 'rb') as f:
+            trusted_certs = f.read()
+        self.channel_credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
+        self.channel = grpc.secure_channel(target=self.target, credentials=self.channel_credentials)
+        self.group_stub = GroupManagementServiceStub(self.channel)
+
+    def create_groups(self, token, name, description, owner_id):
+        """
+        Create groups
+        :param owner_id:
+        :param description:
+        :param name:
+        :param token:
+        :return:
+        """
+
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            group_list = []
+            rep = GroupRepresentation(name=name, realm_roles=[], client_roles=[],
+                                      sub_groups=[], attributes=[], description=description,
+                                      ownerId=owner_id)
+            group_list.append(rep)
+            request = GroupsRequest(groups=group_list)
+
+            return self.group_stub.createGroups(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while creating groups")
+            raise
+
+    def delete_group(self, token, id):
+        """
+        delete group using group id
+        :param token:
+        :param id:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            request = GroupRequest(id=id)
+            return self.group_stub.deleteGroup(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while deleting group")
+            raise
+
+    def find_group(self, token, group_name, group_id):
+        """
+        find group using group name
+        :param token:
+        :param group_name:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            gr = GroupRepresentation(id=group_id, name=group_name)
+            request = GroupRequest(id=group_id, group=gr)
+            return self.group_stub.findGroup(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred finding group")
+            raise
+
+    def get_all_groups(self, token):
+        """
+        Get all groups of tenant
+        :param token:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            request = GroupRequest()
+            return self.group_stub.getAllGroups(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while pulling groups")
+            raise
+
+    def add_user_to_group(self, token, username, group_id, membership_type):
+        """
+        Add user to group
+        :param token:
+        :param username:
+        :param group_id:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            request = UserGroupMappingRequest(username=username, group_id=group_id, membership_type=membership_type)
+            return self.group_stub.addUserToGroup(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while adding user to group")
+            raise
+
+    def remove_user_from_group(self, token, username, group_id):
+        """
+        Remove user from group
+        :param token:
+        :param username:
+        :param group_id:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            request = UserGroupMappingRequest(username=username, group_id=group_id)
+            return self.group_stub.removeUserFromGroup(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while removing user from group")
+            raise
+
+    def add_child_group(self, token, parent_group_id, child_group_id):
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            grm = GroupToGroupMembership(child_id=child_group_id, parent_id=parent_group_id)
+            return self.group_stub.addChildGroupToParentGroup(request=grm, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while adding child group")
+            raise
+
+    def remove_child_group(self, token, parent_group_id, child_group_id):
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            grm = GroupToGroupMembership(child_id=child_group_id, parent_id=parent_group_id)
+            return self.group_stub.removeChildGroupFromParentGroup(request=grm, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while removing child group from group")
+            raise
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/identity_management_client.py b/custos-client-sdks/custos-python-sdk/custos/clients/identity_management_client.py
new file mode 100644
index 0000000..c90a1b2
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/identity_management_client.py
@@ -0,0 +1,240 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+
+import logging
+
+import grpc
+from custos.transport.settings import CustosServerClientSettings
+
+from custos.server.integration.IdentityManagementService_pb2_grpc import IdentityManagementServiceStub
+from custos.server.core.IdentityService_pb2 import AuthenticationRequest, AuthToken, Claim, \
+    GetUserManagementSATokenRequest, \
+    GetTokenRequest, GetOIDCConfiguration, EndSessionRequest
+from custos.server.integration.IdentityManagementService_pb2 import AuthorizationRequest, GetCredentialsRequest, \
+    EndSessionRequest as Er, GetAgentTokenRequest
+from custos.clients.utils.certificate_fetching_rest_client import CertificateFetchingRestClient
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class IdentityManagementClient(object):
+
+    def __init__(self, custos_server_setting):
+        self.custos_settings = custos_server_setting
+        self.target = self.custos_settings.CUSTOS_SERVER_HOST + ":" + str(self.custos_settings.CUSTOS_SERVER_PORT)
+        certManager = CertificateFetchingRestClient(custos_server_setting)
+        certManager.load_certificate()
+        with open(self.custos_settings.CUSTOS_CERT_PATH, 'rb') as f:
+            trusted_certs = f.read()
+        self.channel_credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
+        self.channel = grpc.secure_channel(target=self.target, credentials=self.channel_credentials)
+        self.identity_stub = IdentityManagementServiceStub(self.channel)
+
+    def authenticate(self, token, username, password):
+        """
+        Used for local authentication
+        :param token client credentials
+        :param username Users username
+        :param password Users password
+        :return: Access token
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = AuthenticationRequest(username=username, password=password)
+
+            return self.identity_stub.authenticate(request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred in authenticate, probably due to invalid parameters")
+            raise
+
+    def is_authenticated(self, token, user_access_token, username):
+        """
+        Check access token is valid
+        :param token: client credential token
+        :param user_access_token access token of user
+        :param username
+        :return: status (TRUE, FALSE)
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            claim = Claim(key="username", value=username)
+
+            claims = []
+            claims.append(claim)
+
+            request = AuthToken(accessToken=user_access_token, claims=claims)
+
+            return self.identity_stub.isAuthenticated(request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred in is_authenticated, probably due to invalid parameters")
+            raise
+
+    def get_service_account_access_token(self, token):
+        """
+        Get service account access token
+        :param token: client credentials
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = GetUserManagementSATokenRequest();
+
+            return self.identity_stub.getUserManagementServiceAccountAccessToken(request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred in get_service_account_access_token, probably due to invalid parameters")
+            raise
+
+    def authorize(self, client_id, redirect_uri, response_type, scope, state):
+        """
+        return authorize url of keycloak
+        :param redirect_uri: redirect URI of client
+        :param response_type: response type (code)
+        :param scope: (openid email profile)
+        :param state: (random number)
+        :return:
+        """
+        try:
+            request = AuthorizationRequest(client_id=client_id, redirect_uri=redirect_uri, response_type=response_type,
+                                           scope=scope,
+                                           state=state)
+
+            return self.identity_stub.authorize(request)
+        except Exception:
+            logger.exception("Error occurred in authorize, probably due to invalid parameters")
+            raise
+
+    def token(self, token, redirect_uri=None, code=None, username=None, password=None, refresh_token=None,
+              grant_type=None):
+        """
+        provide user access token
+        :param token: client credentials
+        :param redirect_uri: redirect uri
+        :param code: code returned from token
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = GetTokenRequest(redirect_uri=redirect_uri, code=code,
+                                      username=username, password=password, refresh_token=refresh_token,
+                                      grant_type=grant_type)
+
+            return self.identity_stub.token(request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred in token, probably due to invalid parameters")
+            raise
+
+    def get_credentials(self, token, client_id):
+        """
+        provides IAM and CILogon credentials
+        :param token
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = GetCredentialsRequest(client_id=client_id)
+
+            return self.identity_stub.getCredentials(request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred in get_credentials, probably due to invalid parameters")
+            raise
+
+    def get_oidc_configuration(self, token, client_id):
+        """
+        send the OIDC config
+        :param token client credentials
+        :param client_id
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = GetOIDCConfiguration(client_id=client_id)
+
+            return self.identity_stub.getOIDCConfiguration(request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred in get_OIDC_Configuration, probably due to invalid parameters")
+            raise
+
+    def end_user_session(self, token, refresh_token):
+        """
+        End user session
+        :param token:
+        :param refresh_token:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            body = EndSessionRequest(refresh_token=refresh_token)
+            request = Er(body=body)
+
+            return self.identity_stub.endUserSession(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while ending user session")
+            raise
+
+    def get_agent_token(self, token, client_id, grant_type, refresh_token=None):
+        """
+        Get agent token
+        :param token: base64Encoded(agentId:agentSec)
+        :param client_id: parent Client Id
+        :param grant_type: client_credentials, refresh_token
+        :param refresh_token:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = GetAgentTokenRequest(client_id=client_id, grant_type=grant_type, refresh_token=refresh_token)
+
+            return self.identity_stub.getAgentToken(request=request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred while fetching agent token")
+            raise
+
+    def end_agent_session(self, token, refresh_token):
+        """
+        End user session
+        :param token: base64Encoded(agentId:agentSec)
+        :param refresh_token:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            body = EndSessionRequest(refresh_token=refresh_token)
+            request = Er(body=body)
+
+            return self.identity_stub.endAgentSession(request=request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while ending agent session")
+            raise
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/resource_secret_management_client.py b/custos-client-sdks/custos-python-sdk/custos/clients/resource_secret_management_client.py
new file mode 100644
index 0000000..cf63981
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/resource_secret_management_client.py
@@ -0,0 +1,142 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+
+
+import logging
+import grpc
+
+from custos.transport.settings import CustosServerClientSettings
+
+from custos.server.integration.ResourceSecretManagementService_pb2_grpc import ResourceSecretManagementServiceStub
+from custos.server.core.IdentityService_pb2 import GetJWKSRequest
+from custos.server.core.ResourceSecretService_pb2 import GetSecretRequest, SecretMetadata, ResourceOwnerType, \
+    ResourceSource, \
+    ResourceType, SSHCredential, PasswordCredential, GetResourceCredentialByTokenRequest
+from google.protobuf.json_format import MessageToJson
+from custos.clients.utils.certificate_fetching_rest_client import CertificateFetchingRestClient
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class ResourceSecretManagementClient(object):
+
+    def __init__(self, custos_server_setting):
+        self.custos_settings = custos_server_setting
+        self.target = self.custos_settings.CUSTOS_SERVER_HOST + ":" + str(self.custos_settings.CUSTOS_SERVER_PORT)
+        certManager = CertificateFetchingRestClient(custos_server_setting)
+        certManager.load_certificate()
+        with open(self.custos_settings.CUSTOS_CERT_PATH, 'rb') as f:
+            trusted_certs = f.read()
+        self.channel_credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
+        self.channel = grpc.secure_channel(target=self.target, credentials=self.channel_credentials)
+        self.resource_sec_client = ResourceSecretManagementServiceStub(self.channel)
+
+    def get_secret(self, token, owner_type, resource_type, source, name):
+        """
+        Get secret from secret service
+        :param token:
+        :param owner_type:
+        :param resource_type:
+        :param source:
+        :param name:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            owner_type = ResourceOwnerType.Value(owner_type)
+            resource_type = ResourceType.Value(resource_type)
+            source = ResourceSource.Value(source)
+            met = SecretMetadata(owner_type=owner_type,
+                                 resource_type=resource_type, source=source, name=name)
+            request = GetSecretRequest(metadata=met)
+            msg = self.resource_sec_client.getSecret(request=request, metadata=metadata)
+            return MessageToJson(msg)
+        except Exception:
+            logger.exception("Error occurred while fetching secrets")
+            raise
+
+    def get_JWKS(self, token):
+        """
+        Get JWKS resources
+        :param token:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            request = GetJWKSRequest()
+            msg = self.resource_sec_client.getJWKS(request=request, metadata=metadata)
+            return MessageToJson(msg)
+        except Exception:
+            logger.exception("Error occurred while fetching JWKS request")
+            raise
+
+    def add_ssh_credential(self, token, client_id, owner_id, description):
+
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            secret_metadata = SecretMetadata(client_id=client_id, owner_id=owner_id, description=description)
+            ssh_cred = SSHCredential(metadata=secret_metadata)
+
+            return self.resource_sec_client.addSSHCredential(request=ssh_cred, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred while creating ssh key")
+            raise
+
+    def add_password_credential(self, token, client_id, owner_id, description, password):
+
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            secret_metadata = SecretMetadata(client_id=client_id, owner_id=owner_id, description=description)
+            password_cred = PasswordCredential(metadata=secret_metadata, password=password)
+
+            return self.resource_sec_client.addPasswordCredential(request=password_cred, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred while creating password key")
+            raise
+
+    def get_ssh_credential(self, token, client_id, ssh_credential_token):
+
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            request = GetResourceCredentialByTokenRequest(client_id=client_id, token=ssh_credential_token)
+
+            msg = self.resource_sec_client.getSSHCredential(request=request, metadata=metadata)
+            return MessageToJson(msg)
+        except Exception:
+            logger.exception("Error occurred while creating ssh key")
+            raise
+
+    def get_password_credential(self, token, client_id, password_credential_token):
+
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            request = GetResourceCredentialByTokenRequest(client_id=client_id, token=password_credential_token)
+
+            msg = self.resource_sec_client.getPasswordCredential(request=request, metadata=metadata)
+            return MessageToJson(msg)
+        except Exception:
+            logger.exception("Error occurred while creating password key")
+            raise
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/sharing_management_client.py b/custos-client-sdks/custos-python-sdk/custos/clients/sharing_management_client.py
new file mode 100644
index 0000000..468c5ca
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/sharing_management_client.py
@@ -0,0 +1,120 @@
+import logging
+import grpc
+
+from custos.transport.settings import CustosServerClientSettings
+
+from custos.server.integration.SharingManagementService_pb2_grpc import SharingManagementServiceStub
+
+from custos.server.core.SharingService_pb2 import PermissionType, EntityType, Entity, SharingRequest, \
+    PermissionTypeRequest, EntityRequest, EntityTypeRequest
+from google.protobuf.json_format import MessageToJson
+from custos.clients.utils.certificate_fetching_rest_client import CertificateFetchingRestClient
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class SharingManagementClient(object):
+
+    def __init__(self, custos_server_setting):
+        self.custos_settings = custos_server_setting
+        self.target = self.custos_settings.CUSTOS_SERVER_HOST + ":" + str(self.custos_settings.CUSTOS_SERVER_PORT)
+        certManager = CertificateFetchingRestClient(custos_server_setting)
+        certManager.load_certificate()
+        with open(self.custos_settings.CUSTOS_CERT_PATH, 'rb') as f:
+            trusted_certs = f.read()
+        self.channel_credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
+        self.channel = grpc.secure_channel(target=self.target, credentials=self.channel_credentials)
+        self.sharing_mgt_client = SharingManagementServiceStub(self.channel)
+
+    def create_entity_type(self, token, client_id, id, name, description):
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            entity_type = EntityType(id=id, name=name, description=description)
+            entity_type_req = EntityTypeRequest(client_id=client_id, entity_type=entity_type)
+            return self.sharing_mgt_client.createEntityType(request=entity_type_req, metadata=metadata);
+        except Exception:
+            logger.exception("Error occurred while creating entity type with Id " + id)
+            raise
+
+    def create_permission_type(self, token, client_id, id, name, description):
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            permission_type = PermissionType(id=id, name=name, description=description)
+            permission_type_req = PermissionTypeRequest(client_id=client_id, permission_type=permission_type)
+            return self.sharing_mgt_client.createPermissionType(request=permission_type_req, metadata=metadata);
+        except Exception:
+            logger.exception("Error occurred while creating permission entity type with Id " + id)
+            raise
+
+    def create_entity(self, token, client_id, id, name, description, owner_id, type, parent_id):
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+            entity = Entity(id=id, name=name, description=description, owner_id=owner_id, type=type,
+                            parent_id=parent_id)
+            entity_req = EntityRequest(client_id=client_id, entity=entity)
+            return self.sharing_mgt_client.createEntity(request=entity_req, metadata=metadata);
+        except Exception:
+            logger.exception("Error occurred while creating  entity  with Id " + id)
+            raise
+
+    def share_entity_with_users(self, token, client_id, entity_id, permission_type, user_id):
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            entity = Entity(id=entity_id)
+            permission_type = PermissionType(id=permission_type)
+            owner_ids = []
+            owner_ids.append(user_id)
+            cascade = True
+            sharing_req = SharingRequest(client_id=client_id, entity=entity, permission_type=permission_type,
+                                         owner_id=owner_ids, cascade=cascade)
+            return self.sharing_mgt_client.shareEntityWithUsers(request=sharing_req, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while creating  entity  with Id " + entity_id)
+            raise
+
+    def share_entity_with_groups(self, token, client_id, entity_id, permission_type, group_id):
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            entity = Entity(id=entity_id)
+            permission_type = PermissionType(id=permission_type)
+            owner_ids = []
+            owner_ids.append(group_id)
+            cascade = True
+            sharing_req = SharingRequest(client_id=client_id, entity=entity, permission_type=permission_type,
+                                         owner_id=owner_ids, cascade=cascade)
+            return self.sharing_mgt_client.shareEntityWithGroups(request=sharing_req, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred while creating  entity  with Id " +
+                             entity_id)
+            raise
+
+    def user_has_access(self, token, client_id, entity_id, permission_type, user_id):
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            entity = Entity(id=entity_id)
+            permission_type = PermissionType(id=permission_type)
+            owner_ids = []
+            owner_ids.append(user_id)
+            cascade = True
+            sharing_req = SharingRequest(client_id=client_id, entity=entity, permission_type=permission_type,
+                                         owner_id=owner_ids, cascade=cascade)
+            resl = self.sharing_mgt_client.userHasAccess(request=sharing_req, metadata=metadata)
+
+            if resl.status:
+                return True
+            else:
+                return False
+
+        except Exception:
+            logger.exception("Error occurred while checking for permissions ")
+            raise
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/super_tenant_management_client.py b/custos-client-sdks/custos-python-sdk/custos/clients/super_tenant_management_client.py
new file mode 100644
index 0000000..f7c0463
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/super_tenant_management_client.py
@@ -0,0 +1,80 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+
+import logging
+import grpc
+from custos.server.integration.TenantManagementService_pb2_grpc import TenantManagementServiceStub;
+from custos.server.core.TenantProfileService_pb2 import GetTenantsRequest, UpdateStatusRequest
+from custos.transport.settings import CustosServerClientSettings
+from custos.clients.utils.certificate_fetching_rest_client import CertificateFetchingRestClient
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class SuperTenantManagementClient(object):
+
+    def __init__(self, custos_server_setting):
+        self.custos_settings =custos_server_setting
+        self.target = self.custos_settings.CUSTOS_SERVER_HOST + ":" + str(self.custos_settings.CUSTOS_SERVER_PORT)
+        certManager = CertificateFetchingRestClient(custos_server_setting)
+        certManager.load_certificate()
+        with open(self.custos_settings.CUSTOS_CERT_PATH, 'rb') as f:
+            trusted_certs = f.read()
+        self.channel_credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
+        self.channel = grpc.secure_channel(target=self.target, credentials=self.channel_credentials)
+        self.tenant_stub = TenantManagementServiceStub(self.channel)
+
+    def get_all_tenants(self, token, offset, limit, status, requester_email=None):
+        """
+        Get all tenants
+        :param token admin user token
+        :param offset  omits the initial number of entries
+        :param limit  contains maximum number of entries
+        :param status (ACTIVE, REQUESTED, DENIED, CANCELLED, DEACTIVATED)
+        :return: Tenants
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = GetTenantsRequest(offset=offset, limit=limit, status=status, requester_email=None)
+
+            return self.tenant_stub.getAllTenants(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in get_all_tenants, probably due to invalid parameters")
+            raise
+
+    def update_tenant_status(self, token, client_id, status):
+        """
+        Update tenant status.
+        :param token admin user token
+        :param client_id  client id of tenant to be updated
+        :param status (ACTIVE, REQUESTED, DENIED, CANCELLED, DEACTIVATED)
+        :return: Operation Status
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = UpdateStatusRequest(client_id=client_id, status=status)
+
+            return self.tenant_stub.updateTenantStatus(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in update_tenant_status, probably due to invalid parameters")
+            raise
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/tenant_management_client.py b/custos-client-sdks/custos-python-sdk/custos/clients/tenant_management_client.py
new file mode 100644
index 0000000..def5d00
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/tenant_management_client.py
@@ -0,0 +1,269 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+
+import logging
+import grpc
+from custos.server.integration.TenantManagementService_pb2_grpc import TenantManagementServiceStub
+from custos.server.core.TenantProfileService_pb2 import Tenant, GetTenantsRequest, GetAllTenantsForUserRequest
+from custos.server.core.IamAdminService_pb2 import AddRolesRequest, RoleRepresentation, AddProtocolMapperRequest, \
+    ClaimJSONTypes, MapperTypes
+from custos.server.integration.TenantManagementService_pb2 import GetTenantRequest, \
+    UpdateTenantRequest, DeleteTenantRequest
+from custos.transport.settings import CustosServerClientSettings
+from custos.clients.utils.certificate_fetching_rest_client import CertificateFetchingRestClient
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class TenantManagementClient(object):
+
+    def __init__(self, custos_server_setting):
+        self.custos_settings = custos_server_setting
+        self.target = self.custos_settings.CUSTOS_SERVER_HOST + ":" + str(self.custos_settings.CUSTOS_SERVER_PORT)
+        certManager = CertificateFetchingRestClient(custos_server_setting)
+        certManager.load_certificate()
+        with open(self.custos_settings.CUSTOS_CERT_PATH, 'rb') as f:
+            trusted_certs = f.read()
+        self.channel_credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
+        self.channel = grpc.secure_channel(target=self.target, credentials=self.channel_credentials)
+        self.tenant_stub = TenantManagementServiceStub(self.channel)
+
+    def create_admin_tenant(self, client_name, requester_email, admin_frist_name,
+                            admin_last_name, admin_email, admin_username, admin_password,
+                            contacts, redirect_uris, client_uri, scope, domain, logo_uri, comment):
+        """
+         Creates admin tenant client. Needs to be approved by
+         Custos Admin
+        :return: Custos Credentials
+        """
+        try:
+            tenant = Tenant(client_name=client_name,
+                            requester_email=requester_email,
+                            admin_first_name=admin_frist_name,
+                            admin_last_name=admin_last_name,
+                            admin_email=admin_email,
+                            admin_username=admin_username,
+                            admin_password=admin_password,
+                            contacts=contacts,
+                            redirect_uris=redirect_uris,
+                            client_uri=client_uri,
+                            scope=scope,
+                            domain=domain,
+                            logo_uri=logo_uri,
+                            comment=comment,
+                            application_type="web")
+            return self.tenant_stub.createTenant(tenant)
+        except Exception:
+            logger.exception("Error occurred in create_admin_tenant, probably due to invalid parameters")
+            raise
+
+    def create_tenant(self, client_token, client_name, requester_email, admin_frist_name,
+                      admin_last_name, admin_email, admin_username, admin_password,
+                      contacts, redirect_uris, client_uri, scope, domain, logo_uri, comment):
+        """
+        Creates child tenant under admin tenant. Automatically activates
+        :return: Custos credentials
+        """
+        try:
+            tenant = Tenant(client_name=client_name,
+                            requester_email=requester_email,
+                            admin_first_name=admin_frist_name,
+                            admin_last_name=admin_last_name,
+                            admin_email=admin_email,
+                            admin_username=admin_username,
+                            admin_password=admin_password,
+                            contacts=contacts,
+                            redirect_uris=redirect_uris,
+                            client_uri=client_uri,
+                            scope=scope,
+                            domain=domain,
+                            logo_uri=logo_uri,
+                            comment=comment,
+                            application_type="web")
+            token = "Bearer " + client_token
+            metadata = (('authorization', token),)
+            return self.tenant_stub.createTenant(tenant, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred in create_tenant, probably due to invalid parameters")
+            raise
+
+    def get_tenant(self, client_token, client_id):
+        """
+        Fetch tenant
+        :return: Tenant
+        """
+        try:
+            request = GetTenantRequest(client_id=client_id)
+            token = "Bearer " + client_token
+            metadata = (('authorization', token),)
+            return self.tenant_stub.getTenant(request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred in get_tenant, probably due to invalid parameters")
+            raise
+
+    def update_tenant(self, client_token, client_id, client_name, requester_email, admin_frist_name,
+                      admin_last_name, admin_email, admin_username, admin_password,
+                      contacts, redirect_uris, client_uri, scope, domain, logo_uri, comment):
+        """
+        Update given tenant by client Id
+        :return: updated tenant
+        """
+        try:
+            tenant = Tenant(client_name=client_name,
+                            requester_email=requester_email,
+                            admin_first_name=admin_frist_name,
+                            admin_last_name=admin_last_name,
+                            admin_email=admin_email,
+                            admin_username=admin_username,
+                            admin_password=admin_password,
+                            contacts=contacts,
+                            redirect_uris=redirect_uris,
+                            client_uri=client_uri,
+                            scope=scope,
+                            domain=domain,
+                            logo_uri=logo_uri,
+                            comment=comment,
+                            application_type="web")
+            token = "Bearer " + client_token
+            metadata = (('authorization', token),)
+
+            request = UpdateTenantRequest(client_id=client_id, body=tenant)
+
+            return self.tenant_stub.updateTenant(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in update_tenant, probably due to invalid parameters")
+            raise
+
+    def delete_tenant(self, token, client_id):
+        """
+        Delete given tenant by client Id
+        :return:  void
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = DeleteTenantRequest(client_id=client_id)
+
+            return self.tenant_stub.deleteTenant(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in delete_tenant, probably due to invalid parameters")
+            raise
+
+    def add_tenant_roles(self, token, roles, is_client_level):
+        """
+        :param token
+        :param: roles include realm or client level roles as array
+        :param is_client_level boolean to indicate to add roles to client
+        :return:  void
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            rolesRepArray = []
+
+            for role in roles:
+                rolesRep = RoleRepresentation(name=role['name'], description=role['description'],
+                                              composite=role['composite'])
+                rolesRepArray.append(rolesRep)
+
+            request = AddRolesRequest(roles=rolesRepArray, client_level=is_client_level)
+
+            return self.tenant_stub.addTenantRoles(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in add_tenant_roles, probably due to invalid parameters")
+            raise
+
+    def add_protocol_mapper(self, token, name, attribute_name, claim_name, claim_type, mapper_type,
+                            add_to_id_token, add_to_access_token, add_to_user_info, multi_valued,
+                            aggregate_attribute_values):
+        """
+        Protocol mapper enables to add user attributes, user realm roles or user client roles to be
+        added to ID token, Access token.
+        :param token
+        :param: roles include realm or client level roles as array
+        :param is_client_level boolean to indicate to add roles to client
+        :return:  void
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            wrapped_json_type = ClaimJSONTypes.Value(claim_type)
+            wrapped_mapper_type = MapperTypes.Value(mapper_type)
+
+            request = AddProtocolMapperRequest(name=name,
+                                               attribute_name=attribute_name,
+                                               claim_name=claim_name,
+                                               claim_type=wrapped_json_type,
+                                               mapper_type=wrapped_mapper_type,
+                                               add_to_id_token=add_to_id_token,
+                                               add_to_access_token=add_to_access_token,
+                                               add_to_user_info=add_to_user_info,
+                                               multi_valued=multi_valued,
+                                               aggregate_attribute_values=aggregate_attribute_values
+                                               )
+
+            return self.tenant_stub.addProtocolMapper(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in add_protocol_mapper, probably due to invalid parameters")
+            raise
+
+    def get_child_tenants(self, token, offset, limit, status):
+        """
+        Get child tenants of the calling tenant
+        :param token
+        :param: offset omit initial number of results equalt to offset
+        :param limit results should contain  maximum number of entries
+        :param status (ACTIVE, REQUESTED, DENIED, CANCELLED, DEACTIVATED)
+        :return:  Tenants
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = GetTenantsRequest(offset=offset, limit=limit, status=status)
+
+            return self.tenant_stub.getChildTenants(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in get_child_tenants, probably due to invalid parameters")
+            raise
+
+    def get_all_tenants(self, token, email):
+        """
+        Get all tenants requested by given user
+        :param token
+        :param email get all tenants requested by email
+        :return:  Tenants
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = GetAllTenantsForUserRequest(email=email)
+
+            return self.tenant_stub.getAllTenantsForUser(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in get_all_tenants, probably due to invalid parameters")
+            raise
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/user_management_client.py b/custos-client-sdks/custos-python-sdk/custos/clients/user_management_client.py
new file mode 100644
index 0000000..6fd5159
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/user_management_client.py
@@ -0,0 +1,387 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+
+import logging
+import grpc
+
+from custos.transport.settings import CustosServerClientSettings
+
+from custos.server.integration.UserManagementService_pb2_grpc import UserManagementServiceStub
+from custos.server.core.IamAdminService_pb2 import RegisterUserRequest, UserRepresentation, RegisterUsersRequest, \
+    UserAttribute, \
+    AddUserAttributesRequest, DeleteUserAttributeRequest, UserSearchMetadata, FindUsersRequest, AddUserRolesRequest, \
+    UserSearchRequest, ResetUserPassword, DeleteUserRolesRequest
+from custos.server.core.UserProfileService_pb2 import UserProfile
+from custos.server.integration.UserManagementService_pb2 import LinkUserProfileRequest, UserProfileRequest
+
+from custos.clients.utils.certificate_fetching_rest_client import CertificateFetchingRestClient
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class UserManagementClient(object):
+
+    def __init__(self, custos_server_setting):
+        self.custos_settings = custos_server_setting
+        self.target = self.custos_settings.CUSTOS_SERVER_HOST + ":" + str(self.custos_settings.CUSTOS_SERVER_PORT)
+        certManager = CertificateFetchingRestClient(custos_server_setting)
+        certManager.load_certificate()
+        with open(self.custos_settings.CUSTOS_CERT_PATH, 'rb') as f:
+            trusted_certs = f.read()
+        self.channel_credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
+        self.channel = grpc.secure_channel(target=self.target, credentials=self.channel_credentials)
+        self.user_stub = UserManagementServiceStub(self.channel)
+
+    def register_user(self, token, username, first_name, last_name, password, email, is_temp_password):
+        """
+        Register user in given tenant
+        :param token:  client credentials
+        :param username:
+        :param first_name:
+        :param last_name:
+        :param password:
+        :param email:
+        :param is_temp_password:
+        :return: registration status
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            user = UserRepresentation(username=username, password=password,
+                                      first_name=first_name, last_name=last_name,
+                                      email=email, temporary_password=is_temp_password)
+
+            request = RegisterUserRequest(user=user)
+
+            return self.user_stub.registerUser(request, metadata=metadata)
+        except Exception:
+            logger.exception("Error occurred in register_user, probably due to invalid parameters")
+            raise
+
+    def register_and_enable_users(self, token, users):
+        """
+        register and enable users
+        :param token: admin access token
+        :param users:
+        :return:
+        """
+
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            usersList = []
+
+            for user in users:
+                attributeList = []
+                for atr in user['attributes']:
+                    attribute = UserAttribute(key=atr['key'], values=atr['values'])
+                    attributeList.append(attribute)
+                username = user['username']
+                password = user['password']
+                first_name = user['first_name']
+                last_name = user['last_name']
+                email = user['email']
+                temporary_password = user['temporary_password']
+                realm_roles = user['realm_roles']
+                client_roles = user['client_roles']
+                attributes = attributeList
+                user = UserRepresentation(username=username, password=password,
+                                          first_name=first_name, last_name=last_name,
+                                          email=email, temporary_password=temporary_password,
+                                          realm_roles=realm_roles, client_roles=client_roles,
+                                          attributes=attributes)
+
+                usersList.append(user)
+
+            request = RegisterUsersRequest(users=usersList)
+            return self.user_stub.registerAndEnableUsers(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in register_and_enable_users, probably due to invalid parameters")
+            raise
+
+    def add_user_attributes(self, token, attributes, users):
+        """
+        Add user attributes
+        :param token:
+        :param attributes:
+        :param users:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            attributeList = []
+            for atr in attributes:
+                attribute = UserAttribute(key=atr['key'], values=atr['values'])
+                attributeList.append(attribute)
+
+            request = AddUserAttributesRequest(attributes=attributeList, users=users)
+            return self.user_stub.addUserAttributes(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in add_user_attributes, probably due to invalid parameters")
+            raise
+
+    def delete_user_attributes(self, token, attributes, users):
+        """
+        Delete user attributes
+        :param token: user token
+        :param attributes:
+        :param users:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            attributeList = []
+            for atr in attributes:
+                attribute = UserAttribute(key=atr['key'], values=atr['values'])
+                attributeList.append(attribute)
+
+            request = DeleteUserAttributeRequest(attributes=attributeList, users=users)
+            return self.user_stub.deleteUserAttributes(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in delete_user_attributes, probably due to invalid parameters")
+            raise
+
+    def enable_user(self, token, username):
+        """
+        Enable user request
+        :param token: client credential
+        :param attributes:
+        :param users:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            user = UserSearchMetadata(username=username)
+            request = UserSearchRequest(user=user)
+            return self.user_stub.enableUser(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in enable_user, probably due to invalid parameters")
+            raise
+
+    def add_roles_to_users(self, token, usernames, roles, is_client_level):
+        """
+        Add roles to users
+        :param token: admin token
+        :param usernames list of usersname
+        :param : roles list of roles
+        :param is_client_level to add client level else realm level
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = AddUserRolesRequest(usernames=usernames, roles=roles, client_level=is_client_level)
+            return self.user_stub.addRolesToUsers(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in add_roles_to_users, probably due to invalid parameters")
+            raise
+
+    def is_user_enabled(self, token, username):
+        """
+        Check the weather user is enabled
+        :param token: client credential
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            user = UserSearchMetadata(username=username)
+            request = UserSearchRequest(user=user)
+            return self.user_stub.isUserEnabled(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in is_user_enabled, probably due to invalid parameters")
+            raise
+
+    def is_username_available(self, token, username):
+        """
+        Check the weather username  is available
+        :param token: client credential
+        :param username
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            user = UserSearchMetadata(username=username)
+            request = UserSearchRequest(user=user)
+            return self.user_stub.isUsernameAvailable(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in is_username_available, probably due to invalid parameters")
+            raise
+
+    def get_user(self, token, username):
+        """
+        Get user
+        :param token: client credential
+        :param username
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            user = UserSearchMetadata(username=username)
+            request = UserSearchRequest(user=user)
+            return self.user_stub.getUser(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in get_user, probably due to invalid parameters")
+            raise
+
+    def find_users(self, token, offset, limit, username=None, firstname=None, lastname=None, email=None, ):
+        """
+        Find users
+        :param token: client credential
+        :param username
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            user = UserSearchMetadata(username=username, first_name=firstname, last_name=lastname, email=email)
+            request = FindUsersRequest(user=user, offset=offset, limit=limit)
+            return self.user_stub.findUsers(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in find_users, probably due to invalid parameters")
+            raise
+
+    def reset_password(self, token, username, password):
+        """
+        Reset user password
+        :param token: client credential
+        :param username
+        :param password
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = ResetUserPassword(username=username, password=password)
+            return self.user_stub.resetPassword(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in reset_password, probably due to invalid parameters")
+            raise
+
+    def delete_user(self, token, username):
+        """
+        Delete user from a given realm
+        :param token: admin credentials
+        :param username:
+        :return:
+        """
+
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            user = UserSearchMetadata(username=username)
+            request = UserSearchRequest(user=user)
+            return self.user_stub.deleteUser(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in delete_user, probably due to invalid parameters")
+            raise
+
+    def delete_user_roles(self, token, username, client_roles, realm_roles):
+        """
+        Delete user roles
+        :param token: admin access token
+        :param username:
+        :param client_roles:
+        :param realm_roles:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            request = DeleteUserRolesRequest(username=username, client_roles=client_roles, roles=realm_roles)
+            return self.user_stub.deleteUserRoles(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in delete_user_roles, probably due to invalid parameters")
+            raise
+
+    def update_user_profile(self, token, username, email, first_name, last_name):
+        """
+        Update user profile
+        :param token: user token
+        :param username:
+        :param email:
+        :param first_name:
+        :param last_name:
+        :return:
+        """
+
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            profile = UserProfile(username=username, email=email, first_name=first_name, last_name=last_name)
+            request = UserProfileRequest(user_profile=profile)
+            return self.user_stub.updateUserProfile(request=request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in update_user_profile, probably due to invalid parameters")
+            raise
+
+    def link_user_profile(self, token, current_username, previous_username, linking_attributes=None):
+        """
+        Link existing user profile with previous user profile
+        :param previous_username:
+        :param current_username:
+        :param linking_attributes:
+        :return:
+        """
+        try:
+            token = "Bearer " + token
+            metadata = (('authorization', token),)
+
+            attributeList = []
+            for atr in linking_attributes:
+                attribute = UserAttribute(key=atr['key'], values=atr['values'])
+                attributeList.append(attribute)
+
+            request = LinkUserProfileRequest(current_username=current_username, previous_username=previous_username,
+                                             linking_attributes=attributeList)
+            return self.user_stub.linkUserProfile(request, metadata=metadata)
+
+        except Exception:
+            logger.exception("Error occurred in update_user_profile, probably due to invalid parameters")
+            raise
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/custos/clients/utils/__init__.py
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/custos/clients/utils/__init__.py
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/utils/certificate_fetching_rest_client.py b/custos-client-sdks/custos-python-sdk/custos/clients/utils/certificate_fetching_rest_client.py
new file mode 100644
index 0000000..247372f
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/utils/certificate_fetching_rest_client.py
@@ -0,0 +1,82 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+
+import logging
+
+import OpenSSL
+import requests
+import os
+import datetime
+from urllib3.exceptions import InsecureRequestWarning
+import warnings
+
+requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class CertificateFetchingRestClient(object):
+
+    def __init__(self, custos_server_setting):
+        self.custos_settings = custos_server_setting
+        self.target = self.custos_settings.CUSTOS_SERVER_HOST + ":" + str(self.custos_settings.CUSTOS_SERVER_PORT)
+        self.url = "https://" + self.target + "/resource-secret-management/v1.0.0/secret"
+        self.ownertype = "CUSTOS"
+        self.resource_type = "SERVER_CERTIFICATE"
+        self.params = {
+            'metadata.owner_type': self.ownertype,
+            'metadata.resource_type': self.resource_type
+        }
+
+        self.rootdir = os.path.abspath(os.curdir)
+        encodedStr = utl.get_token(self.custos_settings)
+        self.header = {'Authorization': 'Bearer {}'.format(encodedStr)}
+
+    def load_certificate(self):
+        if not self.__is_certificate_valid():
+            self.__download_certificate()
+
+    def __download_certificate(self):
+        r = requests.get(url=self.url, params=self.params, headers=self.header, stream=True, timeout=60, verify=False)
+        value = r.json()['value']
+        path = self.custos_settings.CUSTOS_CERT_PATH
+        f = open(path, "w")
+        f.write(value)
+
+        try:
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore', InsecureRequestWarning)
+                yield
+        finally:
+            f.close()
+
+    def __is_certificate_valid(self):
+        if os.path.isfile(self.custos_settings.CUSTOS_CERT_PATH):
+            file = open(self.custos_settings.CUSTOS_CERT_PATH)
+            x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
+                                                   file.read())
+            expires = datetime.datetime.strptime(x509.get_notAfter().decode('ascii'), '%Y%m%d%H%M%SZ')
+            now = datetime.datetime.now()
+
+            if now > expires:
+                return False
+            else:
+                return True
+        else:
+            return False
diff --git a/custos-client-sdks/custos-python-sdk/custos/clients/utils/utilities.py b/custos-client-sdks/custos-python-sdk/custos/clients/utils/utilities.py
new file mode 100644
index 0000000..7b42372
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/clients/utils/utilities.py
@@ -0,0 +1,8 @@
+from base64 import b64encode
+
+
+def get_token(custos_settings):
+    tokenStr = custos_settings.CUSTOS_CLIENT_ID + ":" + custos_settings.CUSTOS_CLIENT_SEC
+    tokenByte = tokenStr.encode('utf-8')
+    encodedBytes = b64encode(tokenByte)
+    return encodedBytes.decode('utf-8')
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/custos/samples/__init__.py
similarity index 100%
rename from custos-samples/samples/__init__.py
rename to custos-client-sdks/custos-python-sdk/custos/samples/__init__.py
diff --git a/custos-client-sdks/custos-python-sdk/custos/samples/agent_management_samples.py b/custos-client-sdks/custos-python-sdk/custos/samples/agent_management_samples.py
new file mode 100644
index 0000000..52a0de5
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/samples/agent_management_samples.py
@@ -0,0 +1,49 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+import logging
+from custos.clients.identity_management_client import IdentityManagementClient
+from custos.clients.agent_management_client import AgentManagementClient
+
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+logger = logging.getLogger(__name__)
+
+logger.setLevel(logging.DEBUG)
+# create console handler with a higher log level
+handler = logging.StreamHandler()
+handler.setLevel(logging.DEBUG)
+
+custos_settings = CustosServerClientSettings()
+# load APIServerClient with default configuration
+client = AgentManagementClient(custos_settings)
+id_client = IdentityManagementClient(custos_settings)
+
+token = utl.get_token(custos_settings)
+
+
+def register_and_enable():
+    agent = {
+        "id": "agent-asdasda-ebnmvf",
+        "realm_roles": [],
+        "attributes": [{
+            "key": "agent_cluster_id",
+            "values": ["123123131"]
+        }]
+    }
+    id_res = id_client.token(token, username="isjarana", password="Custos1234", grant_type="password")
+    response = client.register_and_enable_agent(id_res['access_token'], agent)
+    print(response)
diff --git a/custos-client-sdks/custos-python-sdk/custos/samples/group_management_samples.py b/custos-client-sdks/custos-python-sdk/custos/samples/group_management_samples.py
new file mode 100644
index 0000000..586cce5
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/samples/group_management_samples.py
@@ -0,0 +1,63 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+import logging
+from custos.clients.identity_management_client import IdentityManagementClient
+from custos.clients.group_management_client import GroupManagementClient
+
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+logger = logging.getLogger(__name__)
+
+logger.setLevel(logging.DEBUG)
+# create console handler with a higher log level
+handler = logging.StreamHandler()
+handler.setLevel(logging.DEBUG)
+custos_settings = CustosServerClientSettings()
+# load APIServerClient with default configuration
+client = GroupManagementClient(custos_settings)
+id_client = IdentityManagementClient(custos_settings)
+
+token = utl.get_token(custos_settings)
+
+print(token)
+
+
+def create_group():
+    groups = [
+        {
+            "name": "testll",
+            "realm_roles": [],
+            "client_roles": [],
+            "attributes": [{
+                "key": "phone",
+                "values": ["8123915386"]
+            }],
+            "sub_groups": [{
+                "name": "testlj",
+                "realm_roles": [],
+                "client_roles": [],
+                "attributes": [{
+                    "key": "email",
+                    "values": ["irjanith@gmail.com"]
+                }],
+                "sub_groups": []
+            }]
+        }
+    ]
+    id_res = id_client.token(token, username="isjarana", password="Custos1234", grant_type="password")
+    response = client.create_groups(id_res['access_token'], groups)
+    print(response)
diff --git a/custos-client-sdks/custos-python-sdk/custos/samples/identity_management_samples.py b/custos-client-sdks/custos-python-sdk/custos/samples/identity_management_samples.py
new file mode 100644
index 0000000..eca9053
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/samples/identity_management_samples.py
@@ -0,0 +1,70 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+
+import logging
+from custos.clients.identity_management_client import IdentityManagementClient
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+logger = logging.getLogger(__name__)
+
+logger.setLevel(logging.DEBUG)
+# create console handler with a higher log level
+handler = logging.StreamHandler()
+handler.setLevel(logging.DEBUG)
+
+custos_settings = CustosServerClientSettings()
+# load IdentityManagementClient with default configuration
+client = IdentityManagementClient(custos_settings)
+
+main_token = utl.get_token(custos_settings)
+
+
+def authenticate():
+    response = client.authenticate(main_token, "isjarana", "Custos1234")
+    print(response)
+
+
+def is_authenticated():
+    access_token = client.authenticate(main_token, "issa", "1234")
+    response = client.is_authenticated(main_token, access_token.accessToken, "issa")
+    print(response)
+
+
+def get_user_management_access_token():
+    response = client.get_service_account_access_token(token)
+    print(response)
+
+
+def authorize():
+    response = client.authorize("custos-xgect9otrwawa8uwztym-10000006", "http://custos.lk", "code",
+                                "openid email profile", "asdadasdewde")
+    print(response)
+
+
+def token():
+    response = client.token(main_token, "http://custos.lk", "asdasdasdadasd")
+    print(response)
+
+
+def get_credentials():
+    response = client.get_credentials(main_token, "custos-xgect9otrwawa8uwztym-10000006")
+    print(response)
+
+
+def get_OIDC_config():
+    response = client.get_oidc_configuration(main_token, "custos-pv3fqfs9z1hps0xily2t-10000000")
+    print(response)
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/custos/samples/resources/__init__.py
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/custos/samples/resources/__init__.py
diff --git a/custos-client-sdks/custos-python-sdk/custos/samples/resources/cert.pem b/custos-client-sdks/custos-python-sdk/custos/samples/resources/cert.pem
new file mode 100644
index 0000000..2f3d403
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/samples/resources/cert.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFXDCCBESgAwIBAgISAz8ERLSlp4ZA5PlMgMxdWnwKMA0GCSqGSIb3DQEBCwUA
+MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
+ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0yMDAzMDMxMDA0MDhaFw0y
+MDA2MDExMDA0MDhaMBwxGjAYBgNVBAMTEWN1c3Rvcy5zY2lnYXAub3JnMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs6UanPIJWXt94Sp6QuYouBttJj7H
+bRBq6pNfWI480lQvtJuQi/3lxoxzoYP2aVRakuvB1oRbCyRvmWKqn3/AT9BQ050J
+XX0EpAlGYhq8hG8Raq2GM53jumdYlZN2//n6YWaNLdGl10WKroh5w2BHSI5eJ1IT
+ydAq10bt6UxmJFzNf4lnqc9bmrgSOnWMr5XD/PQGklVnOSRmGQNCs7X1dK5ZdUcu
+GwrZFzWoRjt+N/Re3mT+wv9zTVBqzIstT24j6DdjadpRlBOEhVosrQGxqr50Pzle
+/5K0R0/CXohiclb5pkiRv9nJTogKsiX4aSkeG65ZqG0Ex++UahKLYf1XxQIDAQAB
+o4ICaDCCAmQwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
+BgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRQ2uEMFX28RLlE2r5iMXX6
+ZzOdWjAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggrBgEFBQcB
+AQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRzZW5jcnlw
+dC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlw
+dC5vcmcvMBwGA1UdEQQVMBOCEWN1c3Rvcy5zY2lnYXAub3JnMEwGA1UdIARFMEMw
+CAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9j
+cHMubGV0c2VuY3J5cHQub3JnMIIBBgYKKwYBBAHWeQIEAgSB9wSB9ADyAHcA5xLy
+sDd+GmL7jskMYYTx6ns3y1YdESZb8+DzS/JBVG4AAAFwoBE4lgAABAMASDBGAiEA
+8ph79VeXvMg3++LCKlj/KuSDmX0kEqHDytDAaOYywtMCIQC0nqIeWsCyVt/4Fcg5
+fdrATRVaeqCTm9OExbc007++pQB3ALIeBcyLos2KIE6HZvkruYolIGdr2vpw57JJ
+Uy3vi5BeAAABcKAROJYAAAQDAEgwRgIhAIBTEge3DhiyOpVtFcVKRak+xwCQjsId
++Q9Tw+iMcjsAAiEAtOPG66IfExeQZFTbAsl0PBuVbSIWxEFh1pW1G/7F0F4wDQYJ
+KoZIhvcNAQELBQADggEBAIJ924Xkav/zQV8iT46rWN05yXRDopA/Wqhql2aIpO7/
+9pMGS6PuVaNRn8cRQ+9mBGtkdHf5SJqccYraD7mwfJ1v7x7ZVEv/NB5aav1AI89X
+L/o+MtFKU8SGDEXjGyigr/JL52GPIesRqklTTnOQrUM9peUls4lXWRRH5CcfyyNv
+7GWPwh1xqqIUiPiF7afK60Ytu//Ww1YLZPn9HCOV9Pz5BOdZNJGVm6QboM2fW48v
+eC7W929m//adw3oY934lJrYqfYwjMXnU0ZEJe6nUWHQaNDYep2FgZ3PkZb3tuSsf
+7ghMBbvDW94Wb5wx912XzvthJAg23Z0G9bJWgsXh75s=
+-----END CERTIFICATE-----
diff --git a/custos-client-sdks/custos-python-sdk/custos/samples/tenant_management_samples.py b/custos-client-sdks/custos-python-sdk/custos/samples/tenant_management_samples.py
new file mode 100644
index 0000000..9502b45
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/samples/tenant_management_samples.py
@@ -0,0 +1,95 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+import logging
+from custos.clients.tenant_management_client import TenantManagementClient
+from custos.clients.super_tenant_management_client import SuperTenantManagementClient
+from custos.clients.identity_management_client import IdentityManagementClient
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+logger = logging.getLogger(__name__)
+
+logger.setLevel(logging.DEBUG)
+# create console handler with a higher log level
+handler = logging.StreamHandler()
+handler.setLevel(logging.DEBUG)
+
+custos_settings = CustosServerClientSettings()
+# load APIServerClient with default configuration
+client = TenantManagementClient(custos_settings)
+admin_client = SuperTenantManagementClient(custos_settings)
+id_client = IdentityManagementClient(custos_settings)
+
+token = utl.get_token(custos_settings)
+
+
+def create_tenant():
+    contacts = ["2345634324"]
+    redirect_uris = ["http://localhost:8080,http://localhost:8080/user/external_ids"]
+    response = client.create_admin_tenant("SAMPLE",
+                                          "XXX@iu.edu", "First Name", "LastName", "email", "admin",
+                                          "1234",
+                                          contacts, redirect_uris, "https://domain.org/",
+                                          "openid profile email org.cilogon.userinfo", "domain.org",
+                                          "https://domain.org/static/favicon.png", "Galaxy Portal")
+    print(response)
+
+
+def get_tenant():
+    client_id = "custos-8p4baddxvbiusmjorjch-10000401"
+    response = client.get_tenant(client_token=token, client_id=client_id)
+    print(response)
+
+
+def update_tenant():
+    client_id = "custos-6nwoqodstpe5mvcq09lh-10000101"
+    contacts = ["8123915386"]
+    redirect_uris = ["https://custos.scigap.org/callback ", "http://127.0.0.1:8000/auth/callback/",
+                     "http://127.0.0.1:8000/"]
+    response = client.update_tenant(token, client_id, "Custos Portal",
+                                    "irjanith@gmail.com", "Isuru", "Ranawaka", "irjanith@gmail.com", "isjarana",
+                                    "Custos1234",
+                                    contacts, redirect_uris, "https://custos.scigap.org/",
+                                    "openid profile email org.cilogon.userinfo", "domain.org",
+                                    "https://custos.scigap.org/", "Custos Portal")
+    print(response)
+
+
+def add_tenant_roles():
+    roles = [{"name": "testing", "composite": False, "description": "testing realm"}]
+    response = client.add_tenant_roles(token, roles, False)
+    print(response)
+
+
+def add_protocol_mapper():
+    response = client.add_protocol_mapper(token, "phone_atr", "phone", "phone", "STRING", "USER_ATTRIBUTE", True, True,
+                                          True, False, False)
+    print(response)
+
+
+def get_child_tenants():
+    response = client.get_child_tenants(token, 0, 5, "ACTIVE")
+    print(response)
+
+
+def get_all_tenants():
+    response = admin_client.get_all_tenants(token, 0, 5, "ACTIVE")
+    print(response)
+
+
+def delete_tenant():
+    response = client.delete_tenant(token, "custos-pv3fqfs9z1hps0xily2t-10000000")
+    print(response)
diff --git a/custos-client-sdks/custos-python-sdk/custos/samples/user_management_samples.py b/custos-client-sdks/custos-python-sdk/custos/samples/user_management_samples.py
new file mode 100644
index 0000000..a7e3c81
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/samples/user_management_samples.py
@@ -0,0 +1,109 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+import logging
+from custos.clients.user_management_client import UserManagementClient
+from custos.clients.identity_management_client import IdentityManagementClient
+from custos.clients.super_tenant_management_client import SuperTenantManagementClient
+
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+logger = logging.getLogger(__name__)
+
+logger.setLevel(logging.DEBUG)
+# create console handler with a higher log level
+handler = logging.StreamHandler()
+handler.setLevel(logging.DEBUG)
+
+custos_settings = CustosServerClientSettings()
+# load APIServerClient with default configuration
+client = UserManagementClient(custos_settings)
+id_client = IdentityManagementClient(custos_settings)
+
+token = utl.get_token(custos_settings)
+
+admin_client = SuperTenantManagementClient(custos_settings)
+
+
+def register_user():
+    response = client.register_user(token, "TestingUser", "Jhon", "Smith", "12345", "jhon@iu.edu", True)
+    print(response)
+
+
+def register_and_enable_users():
+    response = id_client.authenticate(token, "isjarana", "Custos1234")
+
+    users = [
+        {
+            "username": "test123",
+            "first_name": "user1",
+            "last_name": "last",
+            "password": "1234",
+            "email": "irjanith1@gmail.com",
+            "temporary_password": True,
+            "realm_roles": [
+
+            ],
+            "client_roles": [
+
+            ],
+            "attributes": [
+
+            ]
+        }
+    ]
+
+    response = client.register_and_enable_users(response.accessToken, users)
+    print(response)
+
+
+def add_user_attributes():
+    response = id_client.authenticate(token, "isjarana", "Custos1234")
+    attributes = [
+        {
+            "key": "phone",
+            "values": ["8123915386"]
+        }
+    ]
+    users = ["janith"]
+    response = client.add_user_attributes(response.accessToken, attributes, users)
+    print(response)
+
+
+def delete_user_attributes():
+    response = id_client.authenticate(token, "isjarana", "Custos1234")
+    attributes = [
+        {
+            "key": "phone",
+            "values": ["8123915386"]
+        }
+    ]
+    users = ["janith"]
+    response = client.delete_user_attributes(response.accessToken, attributes, users)
+    print(response)
+
+
+def add_roles_to_user():
+    response = id_client.authenticate(token, "issa", "1234")
+    roles = ["testing"]
+    users = ["janith"]
+    response = client.add_roles_to_users(response.accessToken, users, roles, False)
+    print(response)
+
+
+def find_users():
+    response = client.find_users(token, 0, 3, username="isjarana")
+    print(response)
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/custos/server/__init__.py
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/custos/server/__init__.py
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/AgentProfileService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/AgentProfileService_pb2.py
new file mode 100644
index 0000000..48f05a2
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/AgentProfileService_pb2.py
@@ -0,0 +1,323 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: AgentProfileService.proto
+
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='AgentProfileService.proto',
+  package='org.apache.custos.agent.profile.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n\x19\x41gentProfileService.proto\x12\'org.apache.custos.agent.profile.service\"\xe3\x01\n\x05\x41gent\x12\n\n\x02id\x18\x01 \x01(\t\x12\x44\n\x06status\x18\x02 \x01(\x0e\x32\x34.org.apache.custos.agent.profile.service.AgentStatus\x12\x12\n\ncreated_at\x18\x03 \x01(\x03\x12\x18\n\x10last_modified_at\x18\x04 \x01(\x03\x12\r\n\x05roles\x18\x05 \x03(\t\x12K\n\nattributes\x18\x06 \x03(\x0b\x32\x37.org.apache.custos.agent.profile.service.AgentAttribute\"8\n\x0e\x41gentAttribute\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x03(\t\"_\n\x0c\x41gentRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12=\n\x05\x61gent\x18\x02 \x01(\x0b\x32..org.apache.custos.agent.profile.service.Agent\"!\n\x0fOperationStatus\x12\x0e\n\x06status\x18\x01 \x01(\x08*(\n\x0b\x41gentStatus\x12\x0b\n\x07\x45NABLED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x32\xf4\x03\n\x13\x41gentProfileService\x12t\n\x0b\x63reateAgent\x12\x35.org.apache.custos.agent.profile.service.AgentRequest\x1a..org.apache.custos.agent.profile.service.Agent\x12t\n\x0bupdateAgent\x12\x35.org.apache.custos.agent.profile.service.AgentRequest\x1a..org.apache.custos.agent.profile.service.Agent\x12~\n\x0b\x64\x65leteAgent\x12\x35.org.apache.custos.agent.profile.service.AgentRequest\x1a\x38.org.apache.custos.agent.profile.service.OperationStatus\x12q\n\x08getAgent\x12\x35.org.apache.custos.agent.profile.service.AgentRequest\x1a..org.apache.custos.agent.profile.service.AgentB\x02P\x01\x62\x06proto3'
+)
+
+_AGENTSTATUS = _descriptor.EnumDescriptor(
+  name='AgentStatus',
+  full_name='org.apache.custos.agent.profile.service.AgentStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='ENABLED', index=0, number=0,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='DISABLED', index=1, number=1,
+      serialized_options=None,
+      type=None),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=490,
+  serialized_end=530,
+)
+_sym_db.RegisterEnumDescriptor(_AGENTSTATUS)
+
+AgentStatus = enum_type_wrapper.EnumTypeWrapper(_AGENTSTATUS)
+ENABLED = 0
+DISABLED = 1
+
+
+
+_AGENT = _descriptor.Descriptor(
+  name='Agent',
+  full_name='org.apache.custos.agent.profile.service.Agent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.agent.profile.service.Agent.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.agent.profile.service.Agent.status', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='created_at', full_name='org.apache.custos.agent.profile.service.Agent.created_at', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='last_modified_at', full_name='org.apache.custos.agent.profile.service.Agent.last_modified_at', index=3,
+      number=4, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='org.apache.custos.agent.profile.service.Agent.roles', index=4,
+      number=5, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.agent.profile.service.Agent.attributes', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=71,
+  serialized_end=298,
+)
+
+
+_AGENTATTRIBUTE = _descriptor.Descriptor(
+  name='AgentAttribute',
+  full_name='org.apache.custos.agent.profile.service.AgentAttribute',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.agent.profile.service.AgentAttribute.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.agent.profile.service.AgentAttribute.key', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.agent.profile.service.AgentAttribute.value', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=300,
+  serialized_end=356,
+)
+
+
+_AGENTREQUEST = _descriptor.Descriptor(
+  name='AgentRequest',
+  full_name='org.apache.custos.agent.profile.service.AgentRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.agent.profile.service.AgentRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='agent', full_name='org.apache.custos.agent.profile.service.AgentRequest.agent', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=358,
+  serialized_end=453,
+)
+
+
+_OPERATIONSTATUS = _descriptor.Descriptor(
+  name='OperationStatus',
+  full_name='org.apache.custos.agent.profile.service.OperationStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.agent.profile.service.OperationStatus.status', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=455,
+  serialized_end=488,
+)
+
+_AGENT.fields_by_name['status'].enum_type = _AGENTSTATUS
+_AGENT.fields_by_name['attributes'].message_type = _AGENTATTRIBUTE
+_AGENTREQUEST.fields_by_name['agent'].message_type = _AGENT
+DESCRIPTOR.message_types_by_name['Agent'] = _AGENT
+DESCRIPTOR.message_types_by_name['AgentAttribute'] = _AGENTATTRIBUTE
+DESCRIPTOR.message_types_by_name['AgentRequest'] = _AGENTREQUEST
+DESCRIPTOR.message_types_by_name['OperationStatus'] = _OPERATIONSTATUS
+DESCRIPTOR.enum_types_by_name['AgentStatus'] = _AGENTSTATUS
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Agent = _reflection.GeneratedProtocolMessageType('Agent', (_message.Message,), {
+  'DESCRIPTOR' : _AGENT,
+  '__module__' : 'AgentProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.agent.profile.service.Agent)
+  })
+_sym_db.RegisterMessage(Agent)
+
+AgentAttribute = _reflection.GeneratedProtocolMessageType('AgentAttribute', (_message.Message,), {
+  'DESCRIPTOR' : _AGENTATTRIBUTE,
+  '__module__' : 'AgentProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.agent.profile.service.AgentAttribute)
+  })
+_sym_db.RegisterMessage(AgentAttribute)
+
+AgentRequest = _reflection.GeneratedProtocolMessageType('AgentRequest', (_message.Message,), {
+  'DESCRIPTOR' : _AGENTREQUEST,
+  '__module__' : 'AgentProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.agent.profile.service.AgentRequest)
+  })
+_sym_db.RegisterMessage(AgentRequest)
+
+OperationStatus = _reflection.GeneratedProtocolMessageType('OperationStatus', (_message.Message,), {
+  'DESCRIPTOR' : _OPERATIONSTATUS,
+  '__module__' : 'AgentProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.agent.profile.service.OperationStatus)
+  })
+_sym_db.RegisterMessage(OperationStatus)
+
+
+DESCRIPTOR._options = None
+
+_AGENTPROFILESERVICE = _descriptor.ServiceDescriptor(
+  name='AgentProfileService',
+  full_name='org.apache.custos.agent.profile.service.AgentProfileService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=533,
+  serialized_end=1033,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='createAgent',
+    full_name='org.apache.custos.agent.profile.service.AgentProfileService.createAgent',
+    index=0,
+    containing_service=None,
+    input_type=_AGENTREQUEST,
+    output_type=_AGENT,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateAgent',
+    full_name='org.apache.custos.agent.profile.service.AgentProfileService.updateAgent',
+    index=1,
+    containing_service=None,
+    input_type=_AGENTREQUEST,
+    output_type=_AGENT,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgent',
+    full_name='org.apache.custos.agent.profile.service.AgentProfileService.deleteAgent',
+    index=2,
+    containing_service=None,
+    input_type=_AGENTREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAgent',
+    full_name='org.apache.custos.agent.profile.service.AgentProfileService.getAgent',
+    index=3,
+    containing_service=None,
+    input_type=_AGENTREQUEST,
+    output_type=_AGENT,
+    serialized_options=None,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_AGENTPROFILESERVICE)
+
+DESCRIPTOR.services_by_name['AgentProfileService'] = _AGENTPROFILESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/AgentProfileService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/AgentProfileService_pb2_grpc.py
new file mode 100644
index 0000000..dbb6e42
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/AgentProfileService_pb2_grpc.py
@@ -0,0 +1,97 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import AgentProfileService_pb2 as AgentProfileService__pb2
+
+
+class AgentProfileServiceStub(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.createAgent = channel.unary_unary(
+        '/org.apache.custos.agent.profile.service.AgentProfileService/createAgent',
+        request_serializer=AgentProfileService__pb2.AgentRequest.SerializeToString,
+        response_deserializer=AgentProfileService__pb2.Agent.FromString,
+        )
+    self.updateAgent = channel.unary_unary(
+        '/org.apache.custos.agent.profile.service.AgentProfileService/updateAgent',
+        request_serializer=AgentProfileService__pb2.AgentRequest.SerializeToString,
+        response_deserializer=AgentProfileService__pb2.Agent.FromString,
+        )
+    self.deleteAgent = channel.unary_unary(
+        '/org.apache.custos.agent.profile.service.AgentProfileService/deleteAgent',
+        request_serializer=AgentProfileService__pb2.AgentRequest.SerializeToString,
+        response_deserializer=AgentProfileService__pb2.OperationStatus.FromString,
+        )
+    self.getAgent = channel.unary_unary(
+        '/org.apache.custos.agent.profile.service.AgentProfileService/getAgent',
+        request_serializer=AgentProfileService__pb2.AgentRequest.SerializeToString,
+        response_deserializer=AgentProfileService__pb2.Agent.FromString,
+        )
+
+
+class AgentProfileServiceServicer(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def createAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def updateAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_AgentProfileServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'createAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.createAgent,
+          request_deserializer=AgentProfileService__pb2.AgentRequest.FromString,
+          response_serializer=AgentProfileService__pb2.Agent.SerializeToString,
+      ),
+      'updateAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.updateAgent,
+          request_deserializer=AgentProfileService__pb2.AgentRequest.FromString,
+          response_serializer=AgentProfileService__pb2.Agent.SerializeToString,
+      ),
+      'deleteAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteAgent,
+          request_deserializer=AgentProfileService__pb2.AgentRequest.FromString,
+          response_serializer=AgentProfileService__pb2.OperationStatus.SerializeToString,
+      ),
+      'getAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.getAgent,
+          request_deserializer=AgentProfileService__pb2.AgentRequest.FromString,
+          response_serializer=AgentProfileService__pb2.Agent.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.custos.agent.profile.service.AgentProfileService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/ClusterManagementService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/ClusterManagementService_pb2.py
new file mode 100644
index 0000000..0b196b2
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/ClusterManagementService_pb2.py
@@ -0,0 +1,139 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: ClusterManagementService.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='ClusterManagementService.proto',
+  package='org.apache.custos.cluster.management.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n\x1e\x43lusterManagementService.proto\x12,org.apache.custos.cluster.management.service\"D\n\x1bGetServerCertificateRequest\x12\x12\n\nsecretName\x18\x01 \x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\"3\n\x1cGetServerCertificateResponse\x12\x13\n\x0b\x63\x65rtificate\x18\x01 \x01(\t2\xd0\x01\n\x18\x43lusterManagementService\x12\xb3\x01\n\x1agetCustosServerCertificate\x12I.org.apache.custos.cluster.management.service.GetServerCertificateRequest\x1aJ.org.apache.custos.cluster.management.service.GetServerCertificateResponseB\x02P\x01\x62\x06proto3'
+)
+
+
+
+
+_GETSERVERCERTIFICATEREQUEST = _descriptor.Descriptor(
+  name='GetServerCertificateRequest',
+  full_name='org.apache.custos.cluster.management.service.GetServerCertificateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='secretName', full_name='org.apache.custos.cluster.management.service.GetServerCertificateRequest.secretName', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='namespace', full_name='org.apache.custos.cluster.management.service.GetServerCertificateRequest.namespace', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=80,
+  serialized_end=148,
+)
+
+
+_GETSERVERCERTIFICATERESPONSE = _descriptor.Descriptor(
+  name='GetServerCertificateResponse',
+  full_name='org.apache.custos.cluster.management.service.GetServerCertificateResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='certificate', full_name='org.apache.custos.cluster.management.service.GetServerCertificateResponse.certificate', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=150,
+  serialized_end=201,
+)
+
+DESCRIPTOR.message_types_by_name['GetServerCertificateRequest'] = _GETSERVERCERTIFICATEREQUEST
+DESCRIPTOR.message_types_by_name['GetServerCertificateResponse'] = _GETSERVERCERTIFICATERESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+GetServerCertificateRequest = _reflection.GeneratedProtocolMessageType('GetServerCertificateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETSERVERCERTIFICATEREQUEST,
+  '__module__' : 'ClusterManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.cluster.management.service.GetServerCertificateRequest)
+  })
+_sym_db.RegisterMessage(GetServerCertificateRequest)
+
+GetServerCertificateResponse = _reflection.GeneratedProtocolMessageType('GetServerCertificateResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETSERVERCERTIFICATERESPONSE,
+  '__module__' : 'ClusterManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.cluster.management.service.GetServerCertificateResponse)
+  })
+_sym_db.RegisterMessage(GetServerCertificateResponse)
+
+
+DESCRIPTOR._options = None
+
+_CLUSTERMANAGEMENTSERVICE = _descriptor.ServiceDescriptor(
+  name='ClusterManagementService',
+  full_name='org.apache.custos.cluster.management.service.ClusterManagementService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=204,
+  serialized_end=412,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='getCustosServerCertificate',
+    full_name='org.apache.custos.cluster.management.service.ClusterManagementService.getCustosServerCertificate',
+    index=0,
+    containing_service=None,
+    input_type=_GETSERVERCERTIFICATEREQUEST,
+    output_type=_GETSERVERCERTIFICATERESPONSE,
+    serialized_options=None,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CLUSTERMANAGEMENTSERVICE)
+
+DESCRIPTOR.services_by_name['ClusterManagementService'] = _CLUSTERMANAGEMENTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/ClusterManagementService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/ClusterManagementService_pb2_grpc.py
new file mode 100644
index 0000000..820f6be
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/ClusterManagementService_pb2_grpc.py
@@ -0,0 +1,46 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import ClusterManagementService_pb2 as ClusterManagementService__pb2
+
+
+class ClusterManagementServiceStub(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.getCustosServerCertificate = channel.unary_unary(
+        '/org.apache.custos.cluster.management.service.ClusterManagementService/getCustosServerCertificate',
+        request_serializer=ClusterManagementService__pb2.GetServerCertificateRequest.SerializeToString,
+        response_deserializer=ClusterManagementService__pb2.GetServerCertificateResponse.FromString,
+        )
+
+
+class ClusterManagementServiceServicer(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def getCustosServerCertificate(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_ClusterManagementServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'getCustosServerCertificate': grpc.unary_unary_rpc_method_handler(
+          servicer.getCustosServerCertificate,
+          request_deserializer=ClusterManagementService__pb2.GetServerCertificateRequest.FromString,
+          response_serializer=ClusterManagementService__pb2.GetServerCertificateResponse.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.custos.cluster.management.service.ClusterManagementService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/CredentialStoreService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/CredentialStoreService_pb2.py
new file mode 100644
index 0000000..d951299
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/CredentialStoreService_pb2.py
@@ -0,0 +1,987 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: CredentialStoreService.proto
+
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='CredentialStoreService.proto',
+  package='org.apache.custos.credential.store.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n\x1c\x43redentialStoreService.proto\x12*org.apache.custos.credential.store.service\"\xfb\x01\n\x12\x43redentialMetadata\x12\x0f\n\x07ownerId\x18\x01 \x01(\x03\x12\n\n\x02id\x18\x02 \x01(\t\x12\x0e\n\x06secret\x18\x03 \x01(\t\x12\x1d\n\x15\x63lientSecretExpiredAt\x18\x04 \x01(\x03\x12\x18\n\x10\x63lientIdIssuedAt\x18\x05 \x01(\x03\x12>\n\x04type\x18\x06 \x01(\x0e\x32\x30.org.apache.custos.credential.store.service.Type\x12\x14\n\x0csuper_tenant\x18\x07 \x01(\x08\x12\x13\n\x0bsuper_admin\x18\x08 \x01(\x08\x12\x14\n\x0cinternal_sec\x18\x0b \x01(\t\"s\n\x14GetCredentialRequest\x12\x0f\n\x07ownerId\x18\x01 \x01(\x03\x12\n\n\x02id\x18\x02 \x01(\t\x12>\n\x04type\x18\x03 \x01(\x0e\x32\x30.org.apache.custos.credential.store.service.Type\"+\n\x18GetAllCredentialsRequest\x12\x0f\n\x07ownerId\x18\x01 \x01(\x03\"\xa6\x01\n\x19GetAllCredentialsResponse\x12R\n\nsecretList\x18\x01 \x03(\x0b\x32>.org.apache.custos.credential.store.service.CredentialMetadata\x12\x1a\n\x12requesterUserEmail\x18\x02 \x01(\t\x12\x19\n\x11requesterUsername\x18\x03 \x01(\t\" \n\x0fOperationStatus\x12\r\n\x05state\x18\x01 \x01(\x08\"j\n\x17\x44\x65leteCredentialRequest\x12\x0f\n\x07ownerId\x18\x01 \x01(\x03\x12>\n\x04type\x18\x02 \x01(\x0e\x32\x30.org.apache.custos.credential.store.service.Type\"/\n\x1cGetOperationsMetadataRequest\x12\x0f\n\x07traceId\x18\x01 \x01(\x03\"Z\n\x11OperationMetadata\x12\r\n\x05\x65vent\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\x12\x11\n\ttimeStamp\x18\x03 \x01(\t\x12\x13\n\x0bperformedBy\x18\x04 \x01(\t\"p\n\x1dGetOperationsMetadataResponse\x12O\n\x08metadata\x18\x01 \x03(\x0b\x32=.org.apache.custos.credential.store.service.OperationMetadata\"E\n\x1dGetNewCustosCredentialRequest\x12\x0f\n\x07ownerId\x18\x01 \x01(\x03\x12\x13\n\x0bperformedBy\x18\x02 \x01(\t\"H\n\x1eGetNewCustosCredentialResponse\x12\x10\n\x08\x63lientId\x18\x01 \x01(\t\x12\x14\n\x0c\x63lientSecret\x18\x02 \x01(\t\"5\n\x0cTokenRequest\x12\r\n\x05token\x18\x01 \x01(\t\x12\x16\n\x0eparentClientId\x18\x02 \x01(\t\"%\n\x12GetOwnerIdResponse\x12\x0f\n\x07ownerId\x18\x02 \x01(\x03\"\x80\x02\n\x0b\x43redentials\x12\x15\n\riam_client_id\x18\x01 \x01(\t\x12\x19\n\x11iam_client_secret\x18\x02 \x01(\t\x12\x1a\n\x12\x63i_logon_client_id\x18\x03 \x01(\t\x12\x1e\n\x16\x63i_logon_client_secret\x18\x04 \x01(\t\x12\x18\n\x10\x63ustos_client_id\x18\x05 \x01(\t\x12\x1c\n\x14\x63ustos_client_secret\x18\x06 \x01(\t\x12\"\n\x1a\x63ustos_client_id_issued_at\x18\x07 \x01(\x01\x12\'\n\x1f\x63ustos_client_secret_expired_at\x18\x08 \x01(\x01*U\n\x04Type\x12\n\n\x06\x43USTOS\x10\x00\x12\x07\n\x03IAM\x10\x01\x12\x0b\n\x07\x43ILOGON\x10\x02\x12\x0e\n\nINDIVIDUAL\x10\x03\x12\x10\n\x0c\x41GENT_CLIENT\x10\x04\x12\t\n\x05\x41GENT\x10\x05\x32\x9b\x16\n\x16\x43redentialStoreService\x12\x8c\x01\n\rputCredential\x12>.org.apache.custos.credential.store.service.CredentialMetadata\x1a;.org.apache.custos.credential.store.service.OperationStatus\x12\x94\x01\n\x10\x64\x65leteCredential\x12\x43.org.apache.custos.credential.store.service.DeleteCredentialRequest\x1a;.org.apache.custos.credential.store.service.OperationStatus\x12\x91\x01\n\rgetCredential\x12@.org.apache.custos.credential.store.service.GetCredentialRequest\x1a>.org.apache.custos.credential.store.service.CredentialMetadata\x12\xa0\x01\n\x11getAllCredentials\x12\x44.org.apache.custos.credential.store.service.GetAllCredentialsRequest\x1a\x45.org.apache.custos.credential.store.service.GetAllCredentialsResponse\x12\xab\x01\n\x14getOperationMetadata\x12H.org.apache.custos.credential.store.service.GetOperationsMetadataRequest\x1aI.org.apache.custos.credential.store.service.GetOperationsMetadataResponse\x12\xa3\x01\n\x16getNewCustosCredential\x12I.org.apache.custos.credential.store.service.GetNewCustosCredentialRequest\x1a>.org.apache.custos.credential.store.service.CredentialMetadata\x12\x8f\x01\n\x13getOwnerIdFromToken\x12\x38.org.apache.custos.credential.store.service.TokenRequest\x1a>.org.apache.custos.credential.store.service.GetOwnerIdResponse\x12\x98\x01\n\x1cgetCustosCredentialFromToken\x12\x38.org.apache.custos.credential.store.service.TokenRequest\x1a>.org.apache.custos.credential.store.service.CredentialMetadata\x12\xa3\x01\n\x1fgetCustosCredentialFromClientId\x12@.org.apache.custos.credential.store.service.GetCredentialRequest\x1a>.org.apache.custos.credential.store.service.CredentialMetadata\x12\x9d\x01\n\x1agetAllCredentialsFromToken\x12\x38.org.apache.custos.credential.store.service.TokenRequest\x1a\x45.org.apache.custos.credential.store.service.GetAllCredentialsResponse\x12\x9f\x01\n\x14getMasterCredentials\x12@.org.apache.custos.credential.store.service.GetCredentialRequest\x1a\x45.org.apache.custos.credential.store.service.GetAllCredentialsResponse\x12\xa0\x01\n\x1dgetAllCredentialsFromJWTToken\x12\x38.org.apache.custos.credential.store.service.TokenRequest\x1a\x45.org.apache.custos.credential.store.service.GetAllCredentialsResponse\x12\x88\x01\n\x13getBasicCredentials\x12\x38.org.apache.custos.credential.store.service.TokenRequest\x1a\x37.org.apache.custos.credential.store.service.Credentials\x12\x97\x01\n\x15\x63reateAgentCredential\x12>.org.apache.custos.credential.store.service.CredentialMetadata\x1a>.org.apache.custos.credential.store.service.CredentialMetadata\x12\x96\x01\n\x12getAgentCredential\x12@.org.apache.custos.credential.store.service.GetCredentialRequest\x1a>.org.apache.custos.credential.store.service.CredentialMetadata\x12\x94\x01\n\x15\x64\x65leteAgentCredential\x12>.org.apache.custos.credential.store.service.CredentialMetadata\x1a;.org.apache.custos.credential.store.service.OperationStatus\x12\xa0\x01\n\x1dgetCredentialByAgentBasicAuth\x12\x38.org.apache.custos.credential.store.service.TokenRequest\x1a\x45.org.apache.custos.credential.store.service.GetAllCredentialsResponse\x12\x9f\x01\n\x1cgetCredentialByAgentJWTToken\x12\x38.org.apache.custos.credential.store.service.TokenRequest\x1a\x45.org.apache.custos.credential.store.service.GetAllCredentialsResponseB\x02P\x01\x62\x06proto3'
+)
+
+_TYPE = _descriptor.EnumDescriptor(
+  name='Type',
+  full_name='org.apache.custos.credential.store.service.Type',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='CUSTOS', index=0, number=0,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='IAM', index=1, number=1,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CILOGON', index=2, number=2,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='INDIVIDUAL', index=3, number=3,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='AGENT_CLIENT', index=4, number=4,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='AGENT', index=5, number=5,
+      serialized_options=None,
+      type=None),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=1556,
+  serialized_end=1641,
+)
+_sym_db.RegisterEnumDescriptor(_TYPE)
+
+Type = enum_type_wrapper.EnumTypeWrapper(_TYPE)
+CUSTOS = 0
+IAM = 1
+CILOGON = 2
+INDIVIDUAL = 3
+AGENT_CLIENT = 4
+AGENT = 5
+
+
+
+_CREDENTIALMETADATA = _descriptor.Descriptor(
+  name='CredentialMetadata',
+  full_name='org.apache.custos.credential.store.service.CredentialMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='ownerId', full_name='org.apache.custos.credential.store.service.CredentialMetadata.ownerId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.credential.store.service.CredentialMetadata.id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='secret', full_name='org.apache.custos.credential.store.service.CredentialMetadata.secret', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientSecretExpiredAt', full_name='org.apache.custos.credential.store.service.CredentialMetadata.clientSecretExpiredAt', index=3,
+      number=4, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientIdIssuedAt', full_name='org.apache.custos.credential.store.service.CredentialMetadata.clientIdIssuedAt', index=4,
+      number=5, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.credential.store.service.CredentialMetadata.type', index=5,
+      number=6, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='super_tenant', full_name='org.apache.custos.credential.store.service.CredentialMetadata.super_tenant', index=6,
+      number=7, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='super_admin', full_name='org.apache.custos.credential.store.service.CredentialMetadata.super_admin', index=7,
+      number=8, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='internal_sec', full_name='org.apache.custos.credential.store.service.CredentialMetadata.internal_sec', index=8,
+      number=11, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=77,
+  serialized_end=328,
+)
+
+
+_GETCREDENTIALREQUEST = _descriptor.Descriptor(
+  name='GetCredentialRequest',
+  full_name='org.apache.custos.credential.store.service.GetCredentialRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='ownerId', full_name='org.apache.custos.credential.store.service.GetCredentialRequest.ownerId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.credential.store.service.GetCredentialRequest.id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.credential.store.service.GetCredentialRequest.type', index=2,
+      number=3, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=330,
+  serialized_end=445,
+)
+
+
+_GETALLCREDENTIALSREQUEST = _descriptor.Descriptor(
+  name='GetAllCredentialsRequest',
+  full_name='org.apache.custos.credential.store.service.GetAllCredentialsRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='ownerId', full_name='org.apache.custos.credential.store.service.GetAllCredentialsRequest.ownerId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=447,
+  serialized_end=490,
+)
+
+
+_GETALLCREDENTIALSRESPONSE = _descriptor.Descriptor(
+  name='GetAllCredentialsResponse',
+  full_name='org.apache.custos.credential.store.service.GetAllCredentialsResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='secretList', full_name='org.apache.custos.credential.store.service.GetAllCredentialsResponse.secretList', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='requesterUserEmail', full_name='org.apache.custos.credential.store.service.GetAllCredentialsResponse.requesterUserEmail', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='requesterUsername', full_name='org.apache.custos.credential.store.service.GetAllCredentialsResponse.requesterUsername', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=493,
+  serialized_end=659,
+)
+
+
+_OPERATIONSTATUS = _descriptor.Descriptor(
+  name='OperationStatus',
+  full_name='org.apache.custos.credential.store.service.OperationStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='state', full_name='org.apache.custos.credential.store.service.OperationStatus.state', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=661,
+  serialized_end=693,
+)
+
+
+_DELETECREDENTIALREQUEST = _descriptor.Descriptor(
+  name='DeleteCredentialRequest',
+  full_name='org.apache.custos.credential.store.service.DeleteCredentialRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='ownerId', full_name='org.apache.custos.credential.store.service.DeleteCredentialRequest.ownerId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.credential.store.service.DeleteCredentialRequest.type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=695,
+  serialized_end=801,
+)
+
+
+_GETOPERATIONSMETADATAREQUEST = _descriptor.Descriptor(
+  name='GetOperationsMetadataRequest',
+  full_name='org.apache.custos.credential.store.service.GetOperationsMetadataRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='traceId', full_name='org.apache.custos.credential.store.service.GetOperationsMetadataRequest.traceId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=803,
+  serialized_end=850,
+)
+
+
+_OPERATIONMETADATA = _descriptor.Descriptor(
+  name='OperationMetadata',
+  full_name='org.apache.custos.credential.store.service.OperationMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='org.apache.custos.credential.store.service.OperationMetadata.event', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.credential.store.service.OperationMetadata.status', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='timeStamp', full_name='org.apache.custos.credential.store.service.OperationMetadata.timeStamp', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.credential.store.service.OperationMetadata.performedBy', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=852,
+  serialized_end=942,
+)
+
+
+_GETOPERATIONSMETADATARESPONSE = _descriptor.Descriptor(
+  name='GetOperationsMetadataResponse',
+  full_name='org.apache.custos.credential.store.service.GetOperationsMetadataResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.credential.store.service.GetOperationsMetadataResponse.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=944,
+  serialized_end=1056,
+)
+
+
+_GETNEWCUSTOSCREDENTIALREQUEST = _descriptor.Descriptor(
+  name='GetNewCustosCredentialRequest',
+  full_name='org.apache.custos.credential.store.service.GetNewCustosCredentialRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='ownerId', full_name='org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.ownerId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.credential.store.service.GetNewCustosCredentialRequest.performedBy', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1058,
+  serialized_end=1127,
+)
+
+
+_GETNEWCUSTOSCREDENTIALRESPONSE = _descriptor.Descriptor(
+  name='GetNewCustosCredentialResponse',
+  full_name='org.apache.custos.credential.store.service.GetNewCustosCredentialResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.clientId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientSecret', full_name='org.apache.custos.credential.store.service.GetNewCustosCredentialResponse.clientSecret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1129,
+  serialized_end=1201,
+)
+
+
+_TOKENREQUEST = _descriptor.Descriptor(
+  name='TokenRequest',
+  full_name='org.apache.custos.credential.store.service.TokenRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='token', full_name='org.apache.custos.credential.store.service.TokenRequest.token', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='parentClientId', full_name='org.apache.custos.credential.store.service.TokenRequest.parentClientId', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1203,
+  serialized_end=1256,
+)
+
+
+_GETOWNERIDRESPONSE = _descriptor.Descriptor(
+  name='GetOwnerIdResponse',
+  full_name='org.apache.custos.credential.store.service.GetOwnerIdResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='ownerId', full_name='org.apache.custos.credential.store.service.GetOwnerIdResponse.ownerId', index=0,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1258,
+  serialized_end=1295,
+)
+
+
+_CREDENTIALS = _descriptor.Descriptor(
+  name='Credentials',
+  full_name='org.apache.custos.credential.store.service.Credentials',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='iam_client_id', full_name='org.apache.custos.credential.store.service.Credentials.iam_client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='iam_client_secret', full_name='org.apache.custos.credential.store.service.Credentials.iam_client_secret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='ci_logon_client_id', full_name='org.apache.custos.credential.store.service.Credentials.ci_logon_client_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='ci_logon_client_secret', full_name='org.apache.custos.credential.store.service.Credentials.ci_logon_client_secret', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='custos_client_id', full_name='org.apache.custos.credential.store.service.Credentials.custos_client_id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='custos_client_secret', full_name='org.apache.custos.credential.store.service.Credentials.custos_client_secret', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='custos_client_id_issued_at', full_name='org.apache.custos.credential.store.service.Credentials.custos_client_id_issued_at', index=6,
+      number=7, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='custos_client_secret_expired_at', full_name='org.apache.custos.credential.store.service.Credentials.custos_client_secret_expired_at', index=7,
+      number=8, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1298,
+  serialized_end=1554,
+)
+
+_CREDENTIALMETADATA.fields_by_name['type'].enum_type = _TYPE
+_GETCREDENTIALREQUEST.fields_by_name['type'].enum_type = _TYPE
+_GETALLCREDENTIALSRESPONSE.fields_by_name['secretList'].message_type = _CREDENTIALMETADATA
+_DELETECREDENTIALREQUEST.fields_by_name['type'].enum_type = _TYPE
+_GETOPERATIONSMETADATARESPONSE.fields_by_name['metadata'].message_type = _OPERATIONMETADATA
+DESCRIPTOR.message_types_by_name['CredentialMetadata'] = _CREDENTIALMETADATA
+DESCRIPTOR.message_types_by_name['GetCredentialRequest'] = _GETCREDENTIALREQUEST
+DESCRIPTOR.message_types_by_name['GetAllCredentialsRequest'] = _GETALLCREDENTIALSREQUEST
+DESCRIPTOR.message_types_by_name['GetAllCredentialsResponse'] = _GETALLCREDENTIALSRESPONSE
+DESCRIPTOR.message_types_by_name['OperationStatus'] = _OPERATIONSTATUS
+DESCRIPTOR.message_types_by_name['DeleteCredentialRequest'] = _DELETECREDENTIALREQUEST
+DESCRIPTOR.message_types_by_name['GetOperationsMetadataRequest'] = _GETOPERATIONSMETADATAREQUEST
+DESCRIPTOR.message_types_by_name['OperationMetadata'] = _OPERATIONMETADATA
+DESCRIPTOR.message_types_by_name['GetOperationsMetadataResponse'] = _GETOPERATIONSMETADATARESPONSE
+DESCRIPTOR.message_types_by_name['GetNewCustosCredentialRequest'] = _GETNEWCUSTOSCREDENTIALREQUEST
+DESCRIPTOR.message_types_by_name['GetNewCustosCredentialResponse'] = _GETNEWCUSTOSCREDENTIALRESPONSE
+DESCRIPTOR.message_types_by_name['TokenRequest'] = _TOKENREQUEST
+DESCRIPTOR.message_types_by_name['GetOwnerIdResponse'] = _GETOWNERIDRESPONSE
+DESCRIPTOR.message_types_by_name['Credentials'] = _CREDENTIALS
+DESCRIPTOR.enum_types_by_name['Type'] = _TYPE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+CredentialMetadata = _reflection.GeneratedProtocolMessageType('CredentialMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _CREDENTIALMETADATA,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.CredentialMetadata)
+  })
+_sym_db.RegisterMessage(CredentialMetadata)
+
+GetCredentialRequest = _reflection.GeneratedProtocolMessageType('GetCredentialRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETCREDENTIALREQUEST,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.GetCredentialRequest)
+  })
+_sym_db.RegisterMessage(GetCredentialRequest)
+
+GetAllCredentialsRequest = _reflection.GeneratedProtocolMessageType('GetAllCredentialsRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLCREDENTIALSREQUEST,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.GetAllCredentialsRequest)
+  })
+_sym_db.RegisterMessage(GetAllCredentialsRequest)
+
+GetAllCredentialsResponse = _reflection.GeneratedProtocolMessageType('GetAllCredentialsResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLCREDENTIALSRESPONSE,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.GetAllCredentialsResponse)
+  })
+_sym_db.RegisterMessage(GetAllCredentialsResponse)
+
+OperationStatus = _reflection.GeneratedProtocolMessageType('OperationStatus', (_message.Message,), {
+  'DESCRIPTOR' : _OPERATIONSTATUS,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.OperationStatus)
+  })
+_sym_db.RegisterMessage(OperationStatus)
+
+DeleteCredentialRequest = _reflection.GeneratedProtocolMessageType('DeleteCredentialRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETECREDENTIALREQUEST,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.DeleteCredentialRequest)
+  })
+_sym_db.RegisterMessage(DeleteCredentialRequest)
+
+GetOperationsMetadataRequest = _reflection.GeneratedProtocolMessageType('GetOperationsMetadataRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETOPERATIONSMETADATAREQUEST,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.GetOperationsMetadataRequest)
+  })
+_sym_db.RegisterMessage(GetOperationsMetadataRequest)
+
+OperationMetadata = _reflection.GeneratedProtocolMessageType('OperationMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _OPERATIONMETADATA,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.OperationMetadata)
+  })
+_sym_db.RegisterMessage(OperationMetadata)
+
+GetOperationsMetadataResponse = _reflection.GeneratedProtocolMessageType('GetOperationsMetadataResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETOPERATIONSMETADATARESPONSE,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.GetOperationsMetadataResponse)
+  })
+_sym_db.RegisterMessage(GetOperationsMetadataResponse)
+
+GetNewCustosCredentialRequest = _reflection.GeneratedProtocolMessageType('GetNewCustosCredentialRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETNEWCUSTOSCREDENTIALREQUEST,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.GetNewCustosCredentialRequest)
+  })
+_sym_db.RegisterMessage(GetNewCustosCredentialRequest)
+
+GetNewCustosCredentialResponse = _reflection.GeneratedProtocolMessageType('GetNewCustosCredentialResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETNEWCUSTOSCREDENTIALRESPONSE,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.GetNewCustosCredentialResponse)
+  })
+_sym_db.RegisterMessage(GetNewCustosCredentialResponse)
+
+TokenRequest = _reflection.GeneratedProtocolMessageType('TokenRequest', (_message.Message,), {
+  'DESCRIPTOR' : _TOKENREQUEST,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.TokenRequest)
+  })
+_sym_db.RegisterMessage(TokenRequest)
+
+GetOwnerIdResponse = _reflection.GeneratedProtocolMessageType('GetOwnerIdResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETOWNERIDRESPONSE,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.GetOwnerIdResponse)
+  })
+_sym_db.RegisterMessage(GetOwnerIdResponse)
+
+Credentials = _reflection.GeneratedProtocolMessageType('Credentials', (_message.Message,), {
+  'DESCRIPTOR' : _CREDENTIALS,
+  '__module__' : 'CredentialStoreService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.credential.store.service.Credentials)
+  })
+_sym_db.RegisterMessage(Credentials)
+
+
+DESCRIPTOR._options = None
+
+_CREDENTIALSTORESERVICE = _descriptor.ServiceDescriptor(
+  name='CredentialStoreService',
+  full_name='org.apache.custos.credential.store.service.CredentialStoreService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=1644,
+  serialized_end=4487,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='putCredential',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.putCredential',
+    index=0,
+    containing_service=None,
+    input_type=_CREDENTIALMETADATA,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteCredential',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.deleteCredential',
+    index=1,
+    containing_service=None,
+    input_type=_DELETECREDENTIALREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getCredential',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getCredential',
+    index=2,
+    containing_service=None,
+    input_type=_GETCREDENTIALREQUEST,
+    output_type=_CREDENTIALMETADATA,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllCredentials',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getAllCredentials',
+    index=3,
+    containing_service=None,
+    input_type=_GETALLCREDENTIALSREQUEST,
+    output_type=_GETALLCREDENTIALSRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getOperationMetadata',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getOperationMetadata',
+    index=4,
+    containing_service=None,
+    input_type=_GETOPERATIONSMETADATAREQUEST,
+    output_type=_GETOPERATIONSMETADATARESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getNewCustosCredential',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getNewCustosCredential',
+    index=5,
+    containing_service=None,
+    input_type=_GETNEWCUSTOSCREDENTIALREQUEST,
+    output_type=_CREDENTIALMETADATA,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getOwnerIdFromToken',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getOwnerIdFromToken',
+    index=6,
+    containing_service=None,
+    input_type=_TOKENREQUEST,
+    output_type=_GETOWNERIDRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getCustosCredentialFromToken',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getCustosCredentialFromToken',
+    index=7,
+    containing_service=None,
+    input_type=_TOKENREQUEST,
+    output_type=_CREDENTIALMETADATA,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getCustosCredentialFromClientId',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getCustosCredentialFromClientId',
+    index=8,
+    containing_service=None,
+    input_type=_GETCREDENTIALREQUEST,
+    output_type=_CREDENTIALMETADATA,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllCredentialsFromToken',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getAllCredentialsFromToken',
+    index=9,
+    containing_service=None,
+    input_type=_TOKENREQUEST,
+    output_type=_GETALLCREDENTIALSRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getMasterCredentials',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getMasterCredentials',
+    index=10,
+    containing_service=None,
+    input_type=_GETCREDENTIALREQUEST,
+    output_type=_GETALLCREDENTIALSRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllCredentialsFromJWTToken',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getAllCredentialsFromJWTToken',
+    index=11,
+    containing_service=None,
+    input_type=_TOKENREQUEST,
+    output_type=_GETALLCREDENTIALSRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getBasicCredentials',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getBasicCredentials',
+    index=12,
+    containing_service=None,
+    input_type=_TOKENREQUEST,
+    output_type=_CREDENTIALS,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createAgentCredential',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.createAgentCredential',
+    index=13,
+    containing_service=None,
+    input_type=_CREDENTIALMETADATA,
+    output_type=_CREDENTIALMETADATA,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAgentCredential',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getAgentCredential',
+    index=14,
+    containing_service=None,
+    input_type=_GETCREDENTIALREQUEST,
+    output_type=_CREDENTIALMETADATA,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgentCredential',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.deleteAgentCredential',
+    index=15,
+    containing_service=None,
+    input_type=_CREDENTIALMETADATA,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getCredentialByAgentBasicAuth',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getCredentialByAgentBasicAuth',
+    index=16,
+    containing_service=None,
+    input_type=_TOKENREQUEST,
+    output_type=_GETALLCREDENTIALSRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getCredentialByAgentJWTToken',
+    full_name='org.apache.custos.credential.store.service.CredentialStoreService.getCredentialByAgentJWTToken',
+    index=17,
+    containing_service=None,
+    input_type=_TOKENREQUEST,
+    output_type=_GETALLCREDENTIALSRESPONSE,
+    serialized_options=None,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CREDENTIALSTORESERVICE)
+
+DESCRIPTOR.services_by_name['CredentialStoreService'] = _CREDENTIALSTORESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/CredentialStoreService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/CredentialStoreService_pb2_grpc.py
new file mode 100644
index 0000000..a1d644d
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/CredentialStoreService_pb2_grpc.py
@@ -0,0 +1,335 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import CredentialStoreService_pb2 as CredentialStoreService__pb2
+
+
+class CredentialStoreServiceStub(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.putCredential = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/putCredential',
+        request_serializer=CredentialStoreService__pb2.CredentialMetadata.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.OperationStatus.FromString,
+        )
+    self.deleteCredential = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/deleteCredential',
+        request_serializer=CredentialStoreService__pb2.DeleteCredentialRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.OperationStatus.FromString,
+        )
+    self.getCredential = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getCredential',
+        request_serializer=CredentialStoreService__pb2.GetCredentialRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.CredentialMetadata.FromString,
+        )
+    self.getAllCredentials = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getAllCredentials',
+        request_serializer=CredentialStoreService__pb2.GetAllCredentialsRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.GetAllCredentialsResponse.FromString,
+        )
+    self.getOperationMetadata = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getOperationMetadata',
+        request_serializer=CredentialStoreService__pb2.GetOperationsMetadataRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.GetOperationsMetadataResponse.FromString,
+        )
+    self.getNewCustosCredential = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getNewCustosCredential',
+        request_serializer=CredentialStoreService__pb2.GetNewCustosCredentialRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.CredentialMetadata.FromString,
+        )
+    self.getOwnerIdFromToken = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getOwnerIdFromToken',
+        request_serializer=CredentialStoreService__pb2.TokenRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.GetOwnerIdResponse.FromString,
+        )
+    self.getCustosCredentialFromToken = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getCustosCredentialFromToken',
+        request_serializer=CredentialStoreService__pb2.TokenRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.CredentialMetadata.FromString,
+        )
+    self.getCustosCredentialFromClientId = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getCustosCredentialFromClientId',
+        request_serializer=CredentialStoreService__pb2.GetCredentialRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.CredentialMetadata.FromString,
+        )
+    self.getAllCredentialsFromToken = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getAllCredentialsFromToken',
+        request_serializer=CredentialStoreService__pb2.TokenRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.GetAllCredentialsResponse.FromString,
+        )
+    self.getMasterCredentials = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getMasterCredentials',
+        request_serializer=CredentialStoreService__pb2.GetCredentialRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.GetAllCredentialsResponse.FromString,
+        )
+    self.getAllCredentialsFromJWTToken = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getAllCredentialsFromJWTToken',
+        request_serializer=CredentialStoreService__pb2.TokenRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.GetAllCredentialsResponse.FromString,
+        )
+    self.getBasicCredentials = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getBasicCredentials',
+        request_serializer=CredentialStoreService__pb2.TokenRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.Credentials.FromString,
+        )
+    self.createAgentCredential = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/createAgentCredential',
+        request_serializer=CredentialStoreService__pb2.CredentialMetadata.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.CredentialMetadata.FromString,
+        )
+    self.getAgentCredential = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getAgentCredential',
+        request_serializer=CredentialStoreService__pb2.GetCredentialRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.CredentialMetadata.FromString,
+        )
+    self.deleteAgentCredential = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/deleteAgentCredential',
+        request_serializer=CredentialStoreService__pb2.CredentialMetadata.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.OperationStatus.FromString,
+        )
+    self.getCredentialByAgentBasicAuth = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getCredentialByAgentBasicAuth',
+        request_serializer=CredentialStoreService__pb2.TokenRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.GetAllCredentialsResponse.FromString,
+        )
+    self.getCredentialByAgentJWTToken = channel.unary_unary(
+        '/org.apache.custos.credential.store.service.CredentialStoreService/getCredentialByAgentJWTToken',
+        request_serializer=CredentialStoreService__pb2.TokenRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.GetAllCredentialsResponse.FromString,
+        )
+
+
+class CredentialStoreServiceServicer(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def putCredential(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteCredential(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getCredential(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAllCredentials(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getOperationMetadata(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getNewCustosCredential(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getOwnerIdFromToken(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getCustosCredentialFromToken(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getCustosCredentialFromClientId(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAllCredentialsFromToken(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getMasterCredentials(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAllCredentialsFromJWTToken(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getBasicCredentials(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def createAgentCredential(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAgentCredential(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteAgentCredential(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getCredentialByAgentBasicAuth(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getCredentialByAgentJWTToken(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_CredentialStoreServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'putCredential': grpc.unary_unary_rpc_method_handler(
+          servicer.putCredential,
+          request_deserializer=CredentialStoreService__pb2.CredentialMetadata.FromString,
+          response_serializer=CredentialStoreService__pb2.OperationStatus.SerializeToString,
+      ),
+      'deleteCredential': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteCredential,
+          request_deserializer=CredentialStoreService__pb2.DeleteCredentialRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.OperationStatus.SerializeToString,
+      ),
+      'getCredential': grpc.unary_unary_rpc_method_handler(
+          servicer.getCredential,
+          request_deserializer=CredentialStoreService__pb2.GetCredentialRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.CredentialMetadata.SerializeToString,
+      ),
+      'getAllCredentials': grpc.unary_unary_rpc_method_handler(
+          servicer.getAllCredentials,
+          request_deserializer=CredentialStoreService__pb2.GetAllCredentialsRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.GetAllCredentialsResponse.SerializeToString,
+      ),
+      'getOperationMetadata': grpc.unary_unary_rpc_method_handler(
+          servicer.getOperationMetadata,
+          request_deserializer=CredentialStoreService__pb2.GetOperationsMetadataRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.GetOperationsMetadataResponse.SerializeToString,
+      ),
+      'getNewCustosCredential': grpc.unary_unary_rpc_method_handler(
+          servicer.getNewCustosCredential,
+          request_deserializer=CredentialStoreService__pb2.GetNewCustosCredentialRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.CredentialMetadata.SerializeToString,
+      ),
+      'getOwnerIdFromToken': grpc.unary_unary_rpc_method_handler(
+          servicer.getOwnerIdFromToken,
+          request_deserializer=CredentialStoreService__pb2.TokenRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.GetOwnerIdResponse.SerializeToString,
+      ),
+      'getCustosCredentialFromToken': grpc.unary_unary_rpc_method_handler(
+          servicer.getCustosCredentialFromToken,
+          request_deserializer=CredentialStoreService__pb2.TokenRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.CredentialMetadata.SerializeToString,
+      ),
+      'getCustosCredentialFromClientId': grpc.unary_unary_rpc_method_handler(
+          servicer.getCustosCredentialFromClientId,
+          request_deserializer=CredentialStoreService__pb2.GetCredentialRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.CredentialMetadata.SerializeToString,
+      ),
+      'getAllCredentialsFromToken': grpc.unary_unary_rpc_method_handler(
+          servicer.getAllCredentialsFromToken,
+          request_deserializer=CredentialStoreService__pb2.TokenRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.GetAllCredentialsResponse.SerializeToString,
+      ),
+      'getMasterCredentials': grpc.unary_unary_rpc_method_handler(
+          servicer.getMasterCredentials,
+          request_deserializer=CredentialStoreService__pb2.GetCredentialRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.GetAllCredentialsResponse.SerializeToString,
+      ),
+      'getAllCredentialsFromJWTToken': grpc.unary_unary_rpc_method_handler(
+          servicer.getAllCredentialsFromJWTToken,
+          request_deserializer=CredentialStoreService__pb2.TokenRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.GetAllCredentialsResponse.SerializeToString,
+      ),
+      'getBasicCredentials': grpc.unary_unary_rpc_method_handler(
+          servicer.getBasicCredentials,
+          request_deserializer=CredentialStoreService__pb2.TokenRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.Credentials.SerializeToString,
+      ),
+      'createAgentCredential': grpc.unary_unary_rpc_method_handler(
+          servicer.createAgentCredential,
+          request_deserializer=CredentialStoreService__pb2.CredentialMetadata.FromString,
+          response_serializer=CredentialStoreService__pb2.CredentialMetadata.SerializeToString,
+      ),
+      'getAgentCredential': grpc.unary_unary_rpc_method_handler(
+          servicer.getAgentCredential,
+          request_deserializer=CredentialStoreService__pb2.GetCredentialRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.CredentialMetadata.SerializeToString,
+      ),
+      'deleteAgentCredential': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteAgentCredential,
+          request_deserializer=CredentialStoreService__pb2.CredentialMetadata.FromString,
+          response_serializer=CredentialStoreService__pb2.OperationStatus.SerializeToString,
+      ),
+      'getCredentialByAgentBasicAuth': grpc.unary_unary_rpc_method_handler(
+          servicer.getCredentialByAgentBasicAuth,
+          request_deserializer=CredentialStoreService__pb2.TokenRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.GetAllCredentialsResponse.SerializeToString,
+      ),
+      'getCredentialByAgentJWTToken': grpc.unary_unary_rpc_method_handler(
+          servicer.getCredentialByAgentJWTToken,
+          request_deserializer=CredentialStoreService__pb2.TokenRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.GetAllCredentialsResponse.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.custos.credential.store.service.CredentialStoreService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/FederatedAuthenticationService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/FederatedAuthenticationService_pb2.py
new file mode 100644
index 0000000..b54d60b
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/FederatedAuthenticationService_pb2.py
@@ -0,0 +1,624 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: FederatedAuthenticationService.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='FederatedAuthenticationService.proto',
+  package='org.apache.custos.federated.authentication.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n$FederatedAuthenticationService.proto\x12\x32org.apache.custos.federated.authentication.service\"\xb8\x01\n\x0e\x43lientMetadata\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x12\n\ntenantName\x18\x02 \x01(\t\x12\r\n\x05scope\x18\x03 \x03(\t\x12\x11\n\ttenantURI\x18\x04 \x01(\t\x12\x10\n\x08\x63ontacts\x18\x05 \x03(\t\x12\x0f\n\x07\x63omment\x18\x06 \x01(\t\x12\x14\n\x0credirectURIs\x18\x07 \x03(\t\x12\x10\n\x08\x63lientId\x18\x08 \x01(\t\x12\x13\n\x0bperformedBy\x18\t \x01(\t\"\x98\x01\n\x16RegisterClientResponse\x12\x10\n\x08\x63lientId\x18\x01 \x01(\t\x12\x14\n\x0c\x63lientSecret\x18\x02 \x01(\t\x12\x18\n\x10\x63lientIdIssuedAt\x18\x03 \x01(\x03\x12\x1d\n\x15\x63lientSecretExpiresAt\x18\x04 \x01(\x03\x12\x1d\n\x15\x63lientRegistrationUri\x18\x05 \x01(\t\"6\n\x10GetClientRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x10\n\x08\x63lientId\x18\x02 \x01(\t\"\xf1\x01\n\x11GetClientResponse\x12\x10\n\x08\x63lientId\x18\x01 \x01(\t\x12\x12\n\nclientName\x18\x02 \x01(\t\x12\x14\n\x0credirectURIs\x18\x03 \x03(\t\x12\x12\n\ngrantTypes\x18\x04 \x03(\t\x12\r\n\x05scope\x18\x05 \x03(\t\x12\x18\n\x10\x63lientIdIssuedAt\x18\x06 \x01(\x03\x12\x0f\n\x07\x63omment\x18\x07 \x01(\t\x12\x14\n\x0c\x63lientSecret\x18\x08 \x01(\t\x12\x1d\n\x15\x63lientSecretExpiresAt\x18\t \x01(\x03\x12\x1d\n\x15\x63lientRegistrationUri\x18\n \x01(\t\"N\n\x13\x44\x65leteClientRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x10\n\x08\x63lientId\x18\x02 \x01(\t\x12\x13\n\x0bperformedBy\x18\x03 \x01(\t\"\x07\n\x05\x45mpty\"/\n\x1cGetOperationsMetadataRequest\x12\x0f\n\x07traceId\x18\x01 \x01(\x03\"Z\n\x11OperationMetadata\x12\r\n\x05\x65vent\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\x12\x11\n\ttimeStamp\x18\x03 \x01(\t\x12\x13\n\x0bperformedBy\x18\x04 \x01(\t\"x\n\x1dGetOperationsMetadataResponse\x12W\n\x08metadata\x18\x01 \x03(\x0b\x32\x45.org.apache.custos.federated.authentication.service.OperationMetadata2\xbc\x06\n\x1e\x46\x65\x64\x65ratedAuthenticationService\x12\x9b\x01\n\taddClient\x12\x42.org.apache.custos.federated.authentication.service.ClientMetadata\x1aJ.org.apache.custos.federated.authentication.service.RegisterClientResponse\x12\x8d\x01\n\x0cupdateClient\x12\x42.org.apache.custos.federated.authentication.service.ClientMetadata\x1a\x39.org.apache.custos.federated.authentication.service.Empty\x12\x98\x01\n\tgetClient\x12\x44.org.apache.custos.federated.authentication.service.GetClientRequest\x1a\x45.org.apache.custos.federated.authentication.service.GetClientResponse\x12\x92\x01\n\x0c\x64\x65leteClient\x12G.org.apache.custos.federated.authentication.service.DeleteClientRequest\x1a\x39.org.apache.custos.federated.authentication.service.Empty\x12\xbb\x01\n\x14getOperationMetadata\x12P.org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest\x1aQ.org.apache.custos.federated.authentication.service.GetOperationsMetadataResponseB\x02P\x01\x62\x06proto3'
+)
+
+
+
+
+_CLIENTMETADATA = _descriptor.Descriptor(
+  name='ClientMetadata',
+  full_name='org.apache.custos.federated.authentication.service.ClientMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.federated.authentication.service.ClientMetadata.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenantName', full_name='org.apache.custos.federated.authentication.service.ClientMetadata.tenantName', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.federated.authentication.service.ClientMetadata.scope', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenantURI', full_name='org.apache.custos.federated.authentication.service.ClientMetadata.tenantURI', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='contacts', full_name='org.apache.custos.federated.authentication.service.ClientMetadata.contacts', index=4,
+      number=5, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='comment', full_name='org.apache.custos.federated.authentication.service.ClientMetadata.comment', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='redirectURIs', full_name='org.apache.custos.federated.authentication.service.ClientMetadata.redirectURIs', index=6,
+      number=7, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.federated.authentication.service.ClientMetadata.clientId', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.federated.authentication.service.ClientMetadata.performedBy', index=8,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=93,
+  serialized_end=277,
+)
+
+
+_REGISTERCLIENTRESPONSE = _descriptor.Descriptor(
+  name='RegisterClientResponse',
+  full_name='org.apache.custos.federated.authentication.service.RegisterClientResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.federated.authentication.service.RegisterClientResponse.clientId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientSecret', full_name='org.apache.custos.federated.authentication.service.RegisterClientResponse.clientSecret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientIdIssuedAt', full_name='org.apache.custos.federated.authentication.service.RegisterClientResponse.clientIdIssuedAt', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientSecretExpiresAt', full_name='org.apache.custos.federated.authentication.service.RegisterClientResponse.clientSecretExpiresAt', index=3,
+      number=4, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientRegistrationUri', full_name='org.apache.custos.federated.authentication.service.RegisterClientResponse.clientRegistrationUri', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=280,
+  serialized_end=432,
+)
+
+
+_GETCLIENTREQUEST = _descriptor.Descriptor(
+  name='GetClientRequest',
+  full_name='org.apache.custos.federated.authentication.service.GetClientRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.federated.authentication.service.GetClientRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.federated.authentication.service.GetClientRequest.clientId', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=434,
+  serialized_end=488,
+)
+
+
+_GETCLIENTRESPONSE = _descriptor.Descriptor(
+  name='GetClientResponse',
+  full_name='org.apache.custos.federated.authentication.service.GetClientResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.clientId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientName', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.clientName', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='redirectURIs', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.redirectURIs', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='grantTypes', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.grantTypes', index=3,
+      number=4, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.scope', index=4,
+      number=5, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientIdIssuedAt', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.clientIdIssuedAt', index=5,
+      number=6, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='comment', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.comment', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientSecret', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.clientSecret', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientSecretExpiresAt', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.clientSecretExpiresAt', index=8,
+      number=9, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientRegistrationUri', full_name='org.apache.custos.federated.authentication.service.GetClientResponse.clientRegistrationUri', index=9,
+      number=10, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=491,
+  serialized_end=732,
+)
+
+
+_DELETECLIENTREQUEST = _descriptor.Descriptor(
+  name='DeleteClientRequest',
+  full_name='org.apache.custos.federated.authentication.service.DeleteClientRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.federated.authentication.service.DeleteClientRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.federated.authentication.service.DeleteClientRequest.clientId', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.federated.authentication.service.DeleteClientRequest.performedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=734,
+  serialized_end=812,
+)
+
+
+_EMPTY = _descriptor.Descriptor(
+  name='Empty',
+  full_name='org.apache.custos.federated.authentication.service.Empty',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=814,
+  serialized_end=821,
+)
+
+
+_GETOPERATIONSMETADATAREQUEST = _descriptor.Descriptor(
+  name='GetOperationsMetadataRequest',
+  full_name='org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='traceId', full_name='org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest.traceId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=823,
+  serialized_end=870,
+)
+
+
+_OPERATIONMETADATA = _descriptor.Descriptor(
+  name='OperationMetadata',
+  full_name='org.apache.custos.federated.authentication.service.OperationMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='org.apache.custos.federated.authentication.service.OperationMetadata.event', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.federated.authentication.service.OperationMetadata.status', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='timeStamp', full_name='org.apache.custos.federated.authentication.service.OperationMetadata.timeStamp', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.federated.authentication.service.OperationMetadata.performedBy', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=872,
+  serialized_end=962,
+)
+
+
+_GETOPERATIONSMETADATARESPONSE = _descriptor.Descriptor(
+  name='GetOperationsMetadataResponse',
+  full_name='org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=964,
+  serialized_end=1084,
+)
+
+_GETOPERATIONSMETADATARESPONSE.fields_by_name['metadata'].message_type = _OPERATIONMETADATA
+DESCRIPTOR.message_types_by_name['ClientMetadata'] = _CLIENTMETADATA
+DESCRIPTOR.message_types_by_name['RegisterClientResponse'] = _REGISTERCLIENTRESPONSE
+DESCRIPTOR.message_types_by_name['GetClientRequest'] = _GETCLIENTREQUEST
+DESCRIPTOR.message_types_by_name['GetClientResponse'] = _GETCLIENTRESPONSE
+DESCRIPTOR.message_types_by_name['DeleteClientRequest'] = _DELETECLIENTREQUEST
+DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
+DESCRIPTOR.message_types_by_name['GetOperationsMetadataRequest'] = _GETOPERATIONSMETADATAREQUEST
+DESCRIPTOR.message_types_by_name['OperationMetadata'] = _OPERATIONMETADATA
+DESCRIPTOR.message_types_by_name['GetOperationsMetadataResponse'] = _GETOPERATIONSMETADATARESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+ClientMetadata = _reflection.GeneratedProtocolMessageType('ClientMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _CLIENTMETADATA,
+  '__module__' : 'FederatedAuthenticationService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.federated.authentication.service.ClientMetadata)
+  })
+_sym_db.RegisterMessage(ClientMetadata)
+
+RegisterClientResponse = _reflection.GeneratedProtocolMessageType('RegisterClientResponse', (_message.Message,), {
+  'DESCRIPTOR' : _REGISTERCLIENTRESPONSE,
+  '__module__' : 'FederatedAuthenticationService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.federated.authentication.service.RegisterClientResponse)
+  })
+_sym_db.RegisterMessage(RegisterClientResponse)
+
+GetClientRequest = _reflection.GeneratedProtocolMessageType('GetClientRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETCLIENTREQUEST,
+  '__module__' : 'FederatedAuthenticationService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.federated.authentication.service.GetClientRequest)
+  })
+_sym_db.RegisterMessage(GetClientRequest)
+
+GetClientResponse = _reflection.GeneratedProtocolMessageType('GetClientResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETCLIENTRESPONSE,
+  '__module__' : 'FederatedAuthenticationService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.federated.authentication.service.GetClientResponse)
+  })
+_sym_db.RegisterMessage(GetClientResponse)
+
+DeleteClientRequest = _reflection.GeneratedProtocolMessageType('DeleteClientRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETECLIENTREQUEST,
+  '__module__' : 'FederatedAuthenticationService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.federated.authentication.service.DeleteClientRequest)
+  })
+_sym_db.RegisterMessage(DeleteClientRequest)
+
+Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
+  'DESCRIPTOR' : _EMPTY,
+  '__module__' : 'FederatedAuthenticationService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.federated.authentication.service.Empty)
+  })
+_sym_db.RegisterMessage(Empty)
+
+GetOperationsMetadataRequest = _reflection.GeneratedProtocolMessageType('GetOperationsMetadataRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETOPERATIONSMETADATAREQUEST,
+  '__module__' : 'FederatedAuthenticationService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.federated.authentication.service.GetOperationsMetadataRequest)
+  })
+_sym_db.RegisterMessage(GetOperationsMetadataRequest)
+
+OperationMetadata = _reflection.GeneratedProtocolMessageType('OperationMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _OPERATIONMETADATA,
+  '__module__' : 'FederatedAuthenticationService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.federated.authentication.service.OperationMetadata)
+  })
+_sym_db.RegisterMessage(OperationMetadata)
+
+GetOperationsMetadataResponse = _reflection.GeneratedProtocolMessageType('GetOperationsMetadataResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETOPERATIONSMETADATARESPONSE,
+  '__module__' : 'FederatedAuthenticationService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.federated.authentication.service.GetOperationsMetadataResponse)
+  })
+_sym_db.RegisterMessage(GetOperationsMetadataResponse)
+
+
+DESCRIPTOR._options = None
+
+_FEDERATEDAUTHENTICATIONSERVICE = _descriptor.ServiceDescriptor(
+  name='FederatedAuthenticationService',
+  full_name='org.apache.custos.federated.authentication.service.FederatedAuthenticationService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=1087,
+  serialized_end=1915,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='addClient',
+    full_name='org.apache.custos.federated.authentication.service.FederatedAuthenticationService.addClient',
+    index=0,
+    containing_service=None,
+    input_type=_CLIENTMETADATA,
+    output_type=_REGISTERCLIENTRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateClient',
+    full_name='org.apache.custos.federated.authentication.service.FederatedAuthenticationService.updateClient',
+    index=1,
+    containing_service=None,
+    input_type=_CLIENTMETADATA,
+    output_type=_EMPTY,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getClient',
+    full_name='org.apache.custos.federated.authentication.service.FederatedAuthenticationService.getClient',
+    index=2,
+    containing_service=None,
+    input_type=_GETCLIENTREQUEST,
+    output_type=_GETCLIENTRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteClient',
+    full_name='org.apache.custos.federated.authentication.service.FederatedAuthenticationService.deleteClient',
+    index=3,
+    containing_service=None,
+    input_type=_DELETECLIENTREQUEST,
+    output_type=_EMPTY,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getOperationMetadata',
+    full_name='org.apache.custos.federated.authentication.service.FederatedAuthenticationService.getOperationMetadata',
+    index=4,
+    containing_service=None,
+    input_type=_GETOPERATIONSMETADATAREQUEST,
+    output_type=_GETOPERATIONSMETADATARESPONSE,
+    serialized_options=None,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_FEDERATEDAUTHENTICATIONSERVICE)
+
+DESCRIPTOR.services_by_name['FederatedAuthenticationService'] = _FEDERATEDAUTHENTICATIONSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/FederatedAuthenticationService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/FederatedAuthenticationService_pb2_grpc.py
new file mode 100644
index 0000000..5abc3aa
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/FederatedAuthenticationService_pb2_grpc.py
@@ -0,0 +1,114 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import FederatedAuthenticationService_pb2 as FederatedAuthenticationService__pb2
+
+
+class FederatedAuthenticationServiceStub(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.addClient = channel.unary_unary(
+        '/org.apache.custos.federated.authentication.service.FederatedAuthenticationService/addClient',
+        request_serializer=FederatedAuthenticationService__pb2.ClientMetadata.SerializeToString,
+        response_deserializer=FederatedAuthenticationService__pb2.RegisterClientResponse.FromString,
+        )
+    self.updateClient = channel.unary_unary(
+        '/org.apache.custos.federated.authentication.service.FederatedAuthenticationService/updateClient',
+        request_serializer=FederatedAuthenticationService__pb2.ClientMetadata.SerializeToString,
+        response_deserializer=FederatedAuthenticationService__pb2.Empty.FromString,
+        )
+    self.getClient = channel.unary_unary(
+        '/org.apache.custos.federated.authentication.service.FederatedAuthenticationService/getClient',
+        request_serializer=FederatedAuthenticationService__pb2.GetClientRequest.SerializeToString,
+        response_deserializer=FederatedAuthenticationService__pb2.GetClientResponse.FromString,
+        )
+    self.deleteClient = channel.unary_unary(
+        '/org.apache.custos.federated.authentication.service.FederatedAuthenticationService/deleteClient',
+        request_serializer=FederatedAuthenticationService__pb2.DeleteClientRequest.SerializeToString,
+        response_deserializer=FederatedAuthenticationService__pb2.Empty.FromString,
+        )
+    self.getOperationMetadata = channel.unary_unary(
+        '/org.apache.custos.federated.authentication.service.FederatedAuthenticationService/getOperationMetadata',
+        request_serializer=FederatedAuthenticationService__pb2.GetOperationsMetadataRequest.SerializeToString,
+        response_deserializer=FederatedAuthenticationService__pb2.GetOperationsMetadataResponse.FromString,
+        )
+
+
+class FederatedAuthenticationServiceServicer(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def addClient(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def updateClient(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getClient(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteClient(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getOperationMetadata(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_FederatedAuthenticationServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'addClient': grpc.unary_unary_rpc_method_handler(
+          servicer.addClient,
+          request_deserializer=FederatedAuthenticationService__pb2.ClientMetadata.FromString,
+          response_serializer=FederatedAuthenticationService__pb2.RegisterClientResponse.SerializeToString,
+      ),
+      'updateClient': grpc.unary_unary_rpc_method_handler(
+          servicer.updateClient,
+          request_deserializer=FederatedAuthenticationService__pb2.ClientMetadata.FromString,
+          response_serializer=FederatedAuthenticationService__pb2.Empty.SerializeToString,
+      ),
+      'getClient': grpc.unary_unary_rpc_method_handler(
+          servicer.getClient,
+          request_deserializer=FederatedAuthenticationService__pb2.GetClientRequest.FromString,
+          response_serializer=FederatedAuthenticationService__pb2.GetClientResponse.SerializeToString,
+      ),
+      'deleteClient': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteClient,
+          request_deserializer=FederatedAuthenticationService__pb2.DeleteClientRequest.FromString,
+          response_serializer=FederatedAuthenticationService__pb2.Empty.SerializeToString,
+      ),
+      'getOperationMetadata': grpc.unary_unary_rpc_method_handler(
+          servicer.getOperationMetadata,
+          request_deserializer=FederatedAuthenticationService__pb2.GetOperationsMetadataRequest.FromString,
+          response_serializer=FederatedAuthenticationService__pb2.GetOperationsMetadataResponse.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.custos.federated.authentication.service.FederatedAuthenticationService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/IamAdminService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/IamAdminService_pb2.py
new file mode 100644
index 0000000..a7e7c0e
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/IamAdminService_pb2.py
@@ -0,0 +1,3592 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: IamAdminService.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='IamAdminService.proto',
+  package='org.apache.custos.iam.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x15IamAdminService.proto\x12\x1dorg.apache.custos.iam.service\x1a\x1bgoogle/protobuf/empty.proto\"\x84\x02\n\x12SetUpTenantRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x12\n\ntenantName\x18\x02 \x01(\t\x12\x15\n\radminUsername\x18\x03 \x01(\t\x12\x16\n\x0e\x61\x64minFirstname\x18\x04 \x01(\t\x12\x15\n\radminLastname\x18\x05 \x01(\t\x12\x12\n\nadminEmail\x18\x06 \x01(\t\x12\x15\n\radminPassword\x18\x07 \x01(\t\x12\x11\n\ttenantURL\x18\x08 \x01(\t\x12\x16\n\x0erequesterEmail\x18\t \x01(\t\x12\x14\n\x0credirectURIs\x18\n \x03(\t\x12\x16\n\x0e\x63ustosClientId\x18\x0b \x01(\t\"\xd6\x02\n\x1b\x43onfigureFederateIDPRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12:\n\x04type\x18\x02 \x01(\x0e\x32,.org.apache.custos.iam.service.FederatedIDPs\x12\x10\n\x08\x63lientID\x18\x03 \x01(\t\x12\x11\n\tclientSec\x18\x04 \x01(\t\x12\\\n\tconfigMap\x18\x05 \x03(\x0b\x32I.org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry\x12\x16\n\x0erequesterEmail\x18\x06 \x01(\t\x12\r\n\x05idpId\x18\x07 \x01(\t\x12\r\n\x05scope\x18\x08 \x01(\t\x1a\x30\n\x0e\x43onfigMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"%\n\x13\x46\x65\x64\x65rateIDPResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08\"=\n\x13SetUpTenantResponse\x12\x10\n\x08\x63lientId\x18\x01 \x01(\t\x12\x14\n\x0c\x63lientSecret\x18\x02 \x01(\t\"U\n\x1aIsUsernameAvailableRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x10\n\x08userName\x18\x03 \x01(\t\"$\n\x10\x43heckingResponse\x12\x10\n\x08is_exist\x18\x01 \x01(\x08\"\xc0\x02\n\x12UserRepresentation\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x12\n\nfirst_name\x18\x04 \x01(\t\x12\x11\n\tlast_name\x18\x05 \x01(\t\x12\x10\n\x08password\x18\x06 \x01(\t\x12\r\n\x05\x65mail\x18\x07 \x01(\t\x12\x1a\n\x12temporary_password\x18\x08 \x01(\x08\x12\x13\n\x0brealm_roles\x18\t \x03(\t\x12\x14\n\x0c\x63lient_roles\x18\n \x03(\t\x12@\n\nattributes\x18\x0b \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12\r\n\x05state\x18\x0c \x01(\t\x12\x15\n\rcreation_time\x18\r \x01(\x01\x12\x15\n\rlast_login_at\x18\x0e \x01(\x01\"\xcc\x02\n\x13GroupRepresentation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\x13\n\x0brealm_roles\x18\x03 \x03(\t\x12\x14\n\x0c\x63lient_roles\x18\x04 \x03(\t\x12@\n\nattributes\x18\x05 \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12@\n\x05users\x18\x06 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\x12\x46\n\nsub_groups\x18\x07 \x03(\x0b\x32\x32.org.apache.custos.iam.service.GroupRepresentation\x12\x13\n\x0b\x64\x65scription\x18\x08 \x01(\t\x12\x0f\n\x07ownerId\x18\t \x01(\t\"\xb7\x01\n\x13RegisterUserRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x10\n\x08\x63lientId\x18\x03 \x01(\t\x12\x11\n\tclientSec\x18\x04 \x01(\t\x12?\n\x04user\x18\x05 \x01(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\"\xa6\x01\n\x14RegisterUsersRequest\x12@\n\x05users\x18\x01 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\x12\x10\n\x08tenantId\x18\x02 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\x13\n\x0bperformedBy\x18\x05 \x01(\t\"-\n\x14RegisterUserResponse\x12\x15\n\ris_registered\x18\x01 \x01(\x08\"|\n\x15RegisterUsersResponse\x12\x1b\n\x13\x61llUseresRegistered\x18\x01 \x01(\x08\x12\x46\n\x0b\x66\x61iledUsers\x18\x02 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\"h\n\x12UserSearchMetadata\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x12\n\nfirst_name\x18\x02 \x01(\t\x12\x11\n\tlast_name\x18\x03 \x01(\t\x12\r\n\x05\x65mail\x18\x04 \x01(\t\x12\n\n\x02id\x18\x05 \x01(\t\"\xc0\x01\n\x10\x46indUsersRequest\x12?\n\x04user\x18\x03 \x01(\x0b\x32\x31.org.apache.custos.iam.service.UserSearchMetadata\x12\x0e\n\x06offset\x18\x04 \x01(\x05\x12\r\n\x05limit\x18\x05 \x01(\x05\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x11\n\tclient_id\x18\x06 \x01(\t\x12\x12\n\nclient_sec\x18\x07 \x01(\t\"\xb7\x01\n\x11UserSearchRequest\x12?\n\x04user\x18\x01 \x01(\x0b\x32\x31.org.apache.custos.iam.service.UserSearchMetadata\x12\x10\n\x08tenantId\x18\x02 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x03 \x01(\t\x12\x11\n\tclient_id\x18\x04 \x01(\t\x12\x12\n\nclient_sec\x18\x05 \x01(\t\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\"U\n\x11\x46indUsersResponse\x12@\n\x05users\x18\x01 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\"\x83\x01\n\x11ResetUserPassword\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x10\n\x08password\x18\x02 \x01(\t\x12\x10\n\x08tenantId\x18\x03 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x04 \x01(\t\x12\x10\n\x08\x63lientId\x18\x05 \x01(\t\x12\x11\n\tclientSec\x18\x06 \x01(\t\"\xad\x01\n\x16\x44\x65leteUserRolesRequest\x12\x11\n\ttenant_id\x18\x01 \x01(\x03\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x14\n\x0c\x63lient_roles\x18\x03 \x03(\t\x12\r\n\x05roles\x18\x04 \x03(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x05 \x01(\t\x12\x11\n\tclient_id\x18\x06 \x01(\t\x12\x14\n\x0cperformed_by\x18\x07 \x01(\t\x12\n\n\x02id\x18\x08 \x01(\t\"\xaf\x01\n\x13\x41\x64\x64UserRolesRequest\x12\x11\n\ttenant_id\x18\x01 \x01(\x03\x12\x11\n\tusernames\x18\x02 \x03(\t\x12\r\n\x05roles\x18\x03 \x03(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x04 \x01(\t\x12\x11\n\tclient_id\x18\x05 \x01(\t\x12\x14\n\x0c\x63lient_level\x18\x06 \x01(\x08\x12\x14\n\x0cperformed_by\x18\x07 \x01(\t\x12\x0e\n\x06\x61gents\x18\x08 \x03(\t\"\x82\x01\n\x18UpdateUserProfileRequest\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x01 \x01(\t\x12\x10\n\x08tenantId\x18\x02 \x01(\x03\x12?\n\x04user\x18\x03 \x01(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\"\x1f\n\x0f\x41\x64\x64UserResponse\x12\x0c\n\x04\x63ode\x18\x01 \x01(\t\"/\n\x1cGetOperationsMetadataRequest\x12\x0f\n\x07traceId\x18\x01 \x01(\x03\"Z\n\x11OperationMetadata\x12\r\n\x05\x65vent\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\x12\x11\n\ttimeStamp\x18\x03 \x01(\t\x12\x13\n\x0bperformedBy\x18\x04 \x01(\t\"c\n\x1dGetOperationsMetadataResponse\x12\x42\n\x08metadata\x18\x01 \x03(\x0b\x32\x30.org.apache.custos.iam.service.OperationMetadata\"\'\n\x13\x44\x65leteTenantRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\"\x8f\x01\n\x0f\x41\x64\x64RolesRequest\x12@\n\x05roles\x18\x01 \x03(\x0b\x32\x31.org.apache.custos.iam.service.RoleRepresentation\x12\x14\n\x0c\x63lient_level\x18\x02 \x01(\x08\x12\x11\n\ttenant_id\x18\x03 \x01(\x03\x12\x11\n\tclient_id\x18\x04 \x01(\t\"M\n\x0fGetRolesRequest\x12\x14\n\x0c\x63lient_level\x18\x01 \x01(\x08\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12\x11\n\tclient_id\x18\x03 \x01(\t\"J\n\x12RoleRepresentation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x11\n\tcomposite\x18\x03 \x01(\x08\"[\n\x08\x41llRoles\x12@\n\x05roles\x18\x01 \x03(\x0b\x32\x31.org.apache.custos.iam.service.RoleRepresentation\x12\r\n\x05scope\x18\x02 \x01(\t\"\x88\x03\n\x18\x41\x64\x64ProtocolMapperRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x16\n\x0e\x61ttribute_name\x18\x02 \x01(\t\x12\x12\n\nclaim_name\x18\x03 \x01(\t\x12\x41\n\nclaim_type\x18\x04 \x01(\x0e\x32-.org.apache.custos.iam.service.ClaimJSONTypes\x12\x11\n\ttenant_id\x18\x06 \x01(\x03\x12\x11\n\tclient_id\x18\x07 \x01(\t\x12?\n\x0bmapper_type\x18\x08 \x01(\x0e\x32*.org.apache.custos.iam.service.MapperTypes\x12\x17\n\x0f\x61\x64\x64_to_id_token\x18\t \x01(\x08\x12\x1b\n\x13\x61\x64\x64_to_access_token\x18\n \x01(\x08\x12\x18\n\x10\x61\x64\x64_to_user_info\x18\x0b \x01(\x08\x12\x14\n\x0cmulti_valued\x18\x0c \x01(\x08\x12\"\n\x1a\x61ggregate_attribute_values\x18\r \x01(\x08\"!\n\x0fOperationStatus\x12\x0e\n\x06status\x18\x01 \x01(\x08\"\xcc\x01\n\x18\x41\x64\x64UserAttributesRequest\x12@\n\nattributes\x18\x01 \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12\r\n\x05users\x18\x02 \x03(\t\x12\x11\n\ttenant_id\x18\x03 \x01(\x03\x12\x11\n\tclient_id\x18\x04 \x01(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x05 \x01(\t\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\x12\x0e\n\x06\x61gents\x18\x07 \x03(\t\"\xce\x01\n\x1a\x44\x65leteUserAttributeRequest\x12@\n\nattributes\x18\x01 \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12\r\n\x05users\x18\x02 \x03(\t\x12\x11\n\ttenant_id\x18\x03 \x01(\x03\x12\x11\n\tclient_id\x18\x04 \x01(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x05 \x01(\t\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\x12\x0e\n\x06\x61gents\x18\x07 \x03(\t\",\n\rUserAttribute\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x0e\n\x06values\x18\x02 \x03(\t\"\x8e\x01\n\x17\x45ventPersistenceRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x64min_event\x18\x02 \x01(\x08\x12\r\n\x05\x65vent\x18\x03 \x01(\t\x12\x0e\n\x06\x65nable\x18\x04 \x01(\x08\x12\x18\n\x10persistence_time\x18\x05 \x01(\x03\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\"\xb4\x01\n\rGroupsRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x13\n\x0bperformedBy\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\x11\n\tclientSec\x18\x05 \x01(\t\x12\x42\n\x06groups\x18\x06 \x03(\x0b\x32\x32.org.apache.custos.iam.service.GroupRepresentation\"\xbe\x01\n\x0cGroupRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x13\n\x0bperformedBy\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\x11\n\tclientSec\x18\x05 \x01(\t\x12\n\n\x02id\x18\x06 \x01(\t\x12\x41\n\x05group\x18\x07 \x01(\x0b\x32\x32.org.apache.custos.iam.service.GroupRepresentation\"T\n\x0eGroupsResponse\x12\x42\n\x06groups\x18\x01 \x03(\x0b\x32\x32.org.apache.custos.iam.service.GroupRepresentation\"\xb7\x01\n\x17UserGroupMappingRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x13\n\x0bperformedBy\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\x11\n\tclientSec\x18\x05 \x01(\t\x12\x10\n\x08username\x18\x06 \x01(\t\x12\x10\n\x08group_id\x18\x07 \x01(\t\x12\x17\n\x0fmembership_type\x18\x08 \x01(\t\"\xaf\x01\n\x13\x41gentClientMetadata\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x11\n\ttenantURL\x18\x02 \x01(\t\x12\x14\n\x0credirectURIs\x18\x03 \x03(\t\x12\x12\n\nclientName\x18\x04 \x01(\t\x12\x1e\n\x16\x61\x63\x63\x65ss_token_life_time\x18\x05 \x01(\x03\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x07 \x01(\t\"\xc4\x01\n\x05\x41gent\x12\n\n\x02id\x18\x01 \x01(\t\x12\x13\n\x0brealm_roles\x18\x02 \x03(\t\x12@\n\nattributes\x18\x03 \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12\x11\n\tisEnabled\x18\x04 \x01(\x08\x12\x15\n\rcreation_time\x18\x05 \x01(\x01\x12\x18\n\x10last_modified_at\x18\x06 \x01(\x01\x12\x14\n\x0c\x63lient_roles\x18\x07 \x03(\t\"z\n\x0fGetAllResources\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x10\n\x08\x63lientId\x18\x02 \x01(\t\x12\x43\n\rresource_type\x18\x03 \x01(\x0e\x32,.org.apache.custos.iam.service.ResourceTypes\"\x91\x01\n\x17GetAllResourcesResponse\x12\x34\n\x06\x61gents\x18\x01 \x03(\x0b\x32$.org.apache.custos.iam.service.Agent\x12@\n\x05users\x18\x02 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation*b\n\rFederatedIDPs\x12\x0b\n\x07\x43ILOGON\x10\x00\x12\x0c\n\x08\x46\x41\x43\x45\x42OOK\x10\x01\x12\n\n\x06GOOGLE\x10\x02\x12\x0c\n\x08LINKEDIN\x10\x03\x12\x0b\n\x07TWITTER\x10\x04\x12\x0f\n\x0b\x43USTOM_OIDC\x10\x05*L\n\x0bMapperTypes\x12\x12\n\x0eUSER_ATTRIBUTE\x10\x00\x12\x13\n\x0fUSER_REALM_ROLE\x10\x01\x12\x14\n\x10USER_CLIENT_ROLE\x10\x02*J\n\x0e\x43laimJSONTypes\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04LONG\x10\x01\x12\x0b\n\x07INTEGER\x10\x02\x12\x0b\n\x07\x42OOLEAN\x10\x03\x12\x08\n\x04JSON\x10\x04*$\n\rResourceTypes\x12\x08\n\x04USER\x10\x00\x12\t\n\x05\x41GENT\x10\x01\x32\x81,\n\x0fIamAdminService\x12t\n\x0bsetUPTenant\x12\x31.org.apache.custos.iam.service.SetUpTenantRequest\x1a\x32.org.apache.custos.iam.service.SetUpTenantResponse\x12u\n\x0cupdateTenant\x12\x31.org.apache.custos.iam.service.SetUpTenantRequest\x1a\x32.org.apache.custos.iam.service.SetUpTenantResponse\x12Z\n\x0c\x64\x65leteTenant\x12\x32.org.apache.custos.iam.service.DeleteTenantRequest\x1a\x16.google.protobuf.Empty\x12\x87\x01\n\x15\x63onfigureFederatedIDP\x12:.org.apache.custos.iam.service.ConfigureFederateIDPRequest\x1a\x32.org.apache.custos.iam.service.FederateIDPResponse\x12k\n\x10\x61\x64\x64RolesToTenant\x12..org.apache.custos.iam.service.AddRolesRequest\x1a\'.org.apache.custos.iam.service.AllRoles\x12|\n\x11\x61\x64\x64ProtocolMapper\x12\x37.org.apache.custos.iam.service.AddProtocolMapperRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12k\n\x10getRolesOfTenant\x12..org.apache.custos.iam.service.GetRolesRequest\x1a\'.org.apache.custos.iam.service.AllRoles\x12w\n\x13isUsernameAvailable\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12w\n\x0cregisterUser\x12\x32.org.apache.custos.iam.service.RegisterUserRequest\x1a\x33.org.apache.custos.iam.service.RegisterUserResponse\x12q\n\nenableUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a\x31.org.apache.custos.iam.service.UserRepresentation\x12r\n\x0b\x64isableUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a\x31.org.apache.custos.iam.service.UserRepresentation\x12q\n\risUserEnabled\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12p\n\x0bisUserExist\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a/.org.apache.custos.iam.service.CheckingResponse\x12n\n\x07getUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a\x31.org.apache.custos.iam.service.UserRepresentation\x12n\n\tfindUsers\x12/.org.apache.custos.iam.service.FindUsersRequest\x1a\x30.org.apache.custos.iam.service.FindUsersResponse\x12q\n\rresetPassword\x12\x30.org.apache.custos.iam.service.ResetUserPassword\x1a..org.apache.custos.iam.service.OperationStatus\x12w\n\x13grantAdminPrivilege\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12x\n\x14removeAdminPrivilege\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x83\x01\n\x16registerAndEnableUsers\x12\x33.org.apache.custos.iam.service.RegisterUsersRequest\x1a\x34.org.apache.custos.iam.service.RegisterUsersResponse\x12|\n\x11\x61\x64\x64UserAttributes\x12\x37.org.apache.custos.iam.service.AddUserAttributesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x81\x01\n\x14\x64\x65leteUserAttributes\x12\x39.org.apache.custos.iam.service.DeleteUserAttributeRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12u\n\x0f\x61\x64\x64RolesToUsers\x12\x32.org.apache.custos.iam.service.AddUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12n\n\ndeleteUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12|\n\x13\x64\x65leteRolesFromUser\x12\x35.org.apache.custos.iam.service.DeleteUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12|\n\x11updateUserProfile\x12\x37.org.apache.custos.iam.service.UpdateUserProfileRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x91\x01\n\x14getOperationMetadata\x12;.org.apache.custos.iam.service.GetOperationsMetadataRequest\x1a<.org.apache.custos.iam.service.GetOperationsMetadataResponse\x12\x83\x01\n\x19\x63onfigureEventPersistence\x12\x36.org.apache.custos.iam.service.EventPersistenceRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12k\n\x0c\x63reateGroups\x12,.org.apache.custos.iam.service.GroupsRequest\x1a-.org.apache.custos.iam.service.GroupsResponse\x12n\n\x0bupdateGroup\x12+.org.apache.custos.iam.service.GroupRequest\x1a\x32.org.apache.custos.iam.service.GroupRepresentation\x12j\n\x0b\x64\x65leteGroup\x12+.org.apache.custos.iam.service.GroupRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12l\n\tfindGroup\x12+.org.apache.custos.iam.service.GroupRequest\x1a\x32.org.apache.custos.iam.service.GroupRepresentation\x12j\n\x0cgetAllGroups\x12+.org.apache.custos.iam.service.GroupRequest\x1a-.org.apache.custos.iam.service.GroupsResponse\x12x\n\x0e\x61\x64\x64UserToGroup\x12\x36.org.apache.custos.iam.service.UserGroupMappingRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12}\n\x13removeUserFromGroup\x12\x36.org.apache.custos.iam.service.UserGroupMappingRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12{\n\x11\x63reateAgentClient\x12\x32.org.apache.custos.iam.service.AgentClientMetadata\x1a\x32.org.apache.custos.iam.service.SetUpTenantResponse\x12z\n\x14\x63onfigureAgentClient\x12\x32.org.apache.custos.iam.service.AgentClientMetadata\x1a..org.apache.custos.iam.service.OperationStatus\x12x\n\x14isAgentNameAvailable\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x81\x01\n\x16registerAndEnableAgent\x12\x32.org.apache.custos.iam.service.RegisterUserRequest\x1a\x33.org.apache.custos.iam.service.RegisterUserResponse\x12o\n\x0b\x64\x65leteAgent\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x62\n\x08getAgent\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a$.org.apache.custos.iam.service.Agent\x12p\n\x0c\x64isableAgent\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12o\n\x0b\x65nableAgent\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12}\n\x12\x61\x64\x64\x41gentAttributes\x12\x37.org.apache.custos.iam.service.AddUserAttributesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x82\x01\n\x15\x64\x65leteAgentAttributes\x12\x39.org.apache.custos.iam.service.DeleteUserAttributeRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12u\n\x0f\x61\x64\x64RolesToAgent\x12\x32.org.apache.custos.iam.service.AddUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12y\n\x10\x64\x65leteAgentRoles\x12\x35.org.apache.custos.iam.service.DeleteUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12y\n\x0fgetAllResources\x12..org.apache.custos.iam.service.GetAllResources\x1a\x36.org.apache.custos.iam.service.GetAllResourcesResponseB\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
+
+_FEDERATEDIDPS = _descriptor.EnumDescriptor(
+  name='FederatedIDPs',
+  full_name='org.apache.custos.iam.service.FederatedIDPs',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='CILOGON', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='FACEBOOK', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='GOOGLE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='LINKEDIN', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='TWITTER', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CUSTOM_OIDC', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=6345,
+  serialized_end=6443,
+)
+_sym_db.RegisterEnumDescriptor(_FEDERATEDIDPS)
+
+FederatedIDPs = enum_type_wrapper.EnumTypeWrapper(_FEDERATEDIDPS)
+_MAPPERTYPES = _descriptor.EnumDescriptor(
+  name='MapperTypes',
+  full_name='org.apache.custos.iam.service.MapperTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='USER_ATTRIBUTE', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='USER_REALM_ROLE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='USER_CLIENT_ROLE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=6445,
+  serialized_end=6521,
+)
+_sym_db.RegisterEnumDescriptor(_MAPPERTYPES)
+
+MapperTypes = enum_type_wrapper.EnumTypeWrapper(_MAPPERTYPES)
+_CLAIMJSONTYPES = _descriptor.EnumDescriptor(
+  name='ClaimJSONTypes',
+  full_name='org.apache.custos.iam.service.ClaimJSONTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='STRING', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='LONG', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='INTEGER', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='BOOLEAN', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='JSON', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=6523,
+  serialized_end=6597,
+)
+_sym_db.RegisterEnumDescriptor(_CLAIMJSONTYPES)
+
+ClaimJSONTypes = enum_type_wrapper.EnumTypeWrapper(_CLAIMJSONTYPES)
+_RESOURCETYPES = _descriptor.EnumDescriptor(
+  name='ResourceTypes',
+  full_name='org.apache.custos.iam.service.ResourceTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='USER', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='AGENT', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=6599,
+  serialized_end=6635,
+)
+_sym_db.RegisterEnumDescriptor(_RESOURCETYPES)
+
+ResourceTypes = enum_type_wrapper.EnumTypeWrapper(_RESOURCETYPES)
+CILOGON = 0
+FACEBOOK = 1
+GOOGLE = 2
+LINKEDIN = 3
+TWITTER = 4
+CUSTOM_OIDC = 5
+USER_ATTRIBUTE = 0
+USER_REALM_ROLE = 1
+USER_CLIENT_ROLE = 2
+STRING = 0
+LONG = 1
+INTEGER = 2
+BOOLEAN = 3
+JSON = 4
+USER = 0
+AGENT = 1
+
+
+
+_SETUPTENANTREQUEST = _descriptor.Descriptor(
+  name='SetUpTenantRequest',
+  full_name='org.apache.custos.iam.service.SetUpTenantRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.SetUpTenantRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantName', full_name='org.apache.custos.iam.service.SetUpTenantRequest.tenantName', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminUsername', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminUsername', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminFirstname', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminFirstname', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminLastname', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminLastname', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminEmail', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminEmail', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminPassword', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminPassword', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantURL', full_name='org.apache.custos.iam.service.SetUpTenantRequest.tenantURL', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='requesterEmail', full_name='org.apache.custos.iam.service.SetUpTenantRequest.requesterEmail', index=8,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='redirectURIs', full_name='org.apache.custos.iam.service.SetUpTenantRequest.redirectURIs', index=9,
+      number=10, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='custosClientId', full_name='org.apache.custos.iam.service.SetUpTenantRequest.custosClientId', index=10,
+      number=11, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=86,
+  serialized_end=346,
+)
+
+
+_CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY = _descriptor.Descriptor(
+  name='ConfigMapEntry',
+  full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=b'8\001',
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=643,
+  serialized_end=691,
+)
+
+_CONFIGUREFEDERATEIDPREQUEST = _descriptor.Descriptor(
+  name='ConfigureFederateIDPRequest',
+  full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientID', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.clientID', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.clientSec', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='configMap', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.configMap', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='requesterEmail', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.requesterEmail', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='idpId', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.idpId', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.scope', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[_CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY, ],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=349,
+  serialized_end=691,
+)
+
+
+_FEDERATEIDPRESPONSE = _descriptor.Descriptor(
+  name='FederateIDPResponse',
+  full_name='org.apache.custos.iam.service.FederateIDPResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.iam.service.FederateIDPResponse.status', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=693,
+  serialized_end=730,
+)
+
+
+_SETUPTENANTRESPONSE = _descriptor.Descriptor(
+  name='SetUpTenantResponse',
+  full_name='org.apache.custos.iam.service.SetUpTenantResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.SetUpTenantResponse.clientId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSecret', full_name='org.apache.custos.iam.service.SetUpTenantResponse.clientSecret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=732,
+  serialized_end=793,
+)
+
+
+_ISUSERNAMEAVAILABLEREQUEST = _descriptor.Descriptor(
+  name='IsUsernameAvailableRequest',
+  full_name='org.apache.custos.iam.service.IsUsernameAvailableRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.IsUsernameAvailableRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.IsUsernameAvailableRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='userName', full_name='org.apache.custos.iam.service.IsUsernameAvailableRequest.userName', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=795,
+  serialized_end=880,
+)
+
+
+_CHECKINGRESPONSE = _descriptor.Descriptor(
+  name='CheckingResponse',
+  full_name='org.apache.custos.iam.service.CheckingResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='is_exist', full_name='org.apache.custos.iam.service.CheckingResponse.is_exist', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=882,
+  serialized_end=918,
+)
+
+
+_USERREPRESENTATION = _descriptor.Descriptor(
+  name='UserRepresentation',
+  full_name='org.apache.custos.iam.service.UserRepresentation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.UserRepresentation.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.UserRepresentation.username', index=1,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='first_name', full_name='org.apache.custos.iam.service.UserRepresentation.first_name', index=2,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_name', full_name='org.apache.custos.iam.service.UserRepresentation.last_name', index=3,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='password', full_name='org.apache.custos.iam.service.UserRepresentation.password', index=4,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='email', full_name='org.apache.custos.iam.service.UserRepresentation.email', index=5,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='temporary_password', full_name='org.apache.custos.iam.service.UserRepresentation.temporary_password', index=6,
+      number=8, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='realm_roles', full_name='org.apache.custos.iam.service.UserRepresentation.realm_roles', index=7,
+      number=9, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.iam.service.UserRepresentation.client_roles', index=8,
+      number=10, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.UserRepresentation.attributes', index=9,
+      number=11, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='state', full_name='org.apache.custos.iam.service.UserRepresentation.state', index=10,
+      number=12, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='creation_time', full_name='org.apache.custos.iam.service.UserRepresentation.creation_time', index=11,
+      number=13, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_login_at', full_name='org.apache.custos.iam.service.UserRepresentation.last_login_at', index=12,
+      number=14, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=921,
+  serialized_end=1241,
+)
+
+
+_GROUPREPRESENTATION = _descriptor.Descriptor(
+  name='GroupRepresentation',
+  full_name='org.apache.custos.iam.service.GroupRepresentation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.iam.service.GroupRepresentation.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.GroupRepresentation.id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='realm_roles', full_name='org.apache.custos.iam.service.GroupRepresentation.realm_roles', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.iam.service.GroupRepresentation.client_roles', index=3,
+      number=4, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.GroupRepresentation.attributes', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.GroupRepresentation.users', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='sub_groups', full_name='org.apache.custos.iam.service.GroupRepresentation.sub_groups', index=6,
+      number=7, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='org.apache.custos.iam.service.GroupRepresentation.description', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='ownerId', full_name='org.apache.custos.iam.service.GroupRepresentation.ownerId', index=8,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1244,
+  serialized_end=1576,
+)
+
+
+_REGISTERUSERREQUEST = _descriptor.Descriptor(
+  name='RegisterUserRequest',
+  full_name='org.apache.custos.iam.service.RegisterUserRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.RegisterUserRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.RegisterUserRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.RegisterUserRequest.clientId', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.RegisterUserRequest.clientSec', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='user', full_name='org.apache.custos.iam.service.RegisterUserRequest.user', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.RegisterUserRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1579,
+  serialized_end=1762,
+)
+
+
+_REGISTERUSERSREQUEST = _descriptor.Descriptor(
+  name='RegisterUsersRequest',
+  full_name='org.apache.custos.iam.service.RegisterUsersRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.RegisterUsersRequest.users', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.RegisterUsersRequest.tenantId', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.RegisterUsersRequest.accessToken', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.RegisterUsersRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.RegisterUsersRequest.performedBy', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1765,
+  serialized_end=1931,
+)
+
+
+_REGISTERUSERRESPONSE = _descriptor.Descriptor(
+  name='RegisterUserResponse',
+  full_name='org.apache.custos.iam.service.RegisterUserResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='is_registered', full_name='org.apache.custos.iam.service.RegisterUserResponse.is_registered', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1933,
+  serialized_end=1978,
+)
+
+
+_REGISTERUSERSRESPONSE = _descriptor.Descriptor(
+  name='RegisterUsersResponse',
+  full_name='org.apache.custos.iam.service.RegisterUsersResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='allUseresRegistered', full_name='org.apache.custos.iam.service.RegisterUsersResponse.allUseresRegistered', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='failedUsers', full_name='org.apache.custos.iam.service.RegisterUsersResponse.failedUsers', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1980,
+  serialized_end=2104,
+)
+
+
+_USERSEARCHMETADATA = _descriptor.Descriptor(
+  name='UserSearchMetadata',
+  full_name='org.apache.custos.iam.service.UserSearchMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.UserSearchMetadata.username', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='first_name', full_name='org.apache.custos.iam.service.UserSearchMetadata.first_name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_name', full_name='org.apache.custos.iam.service.UserSearchMetadata.last_name', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='email', full_name='org.apache.custos.iam.service.UserSearchMetadata.email', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.UserSearchMetadata.id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2106,
+  serialized_end=2210,
+)
+
+
+_FINDUSERSREQUEST = _descriptor.Descriptor(
+  name='FindUsersRequest',
+  full_name='org.apache.custos.iam.service.FindUsersRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='user', full_name='org.apache.custos.iam.service.FindUsersRequest.user', index=0,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='offset', full_name='org.apache.custos.iam.service.FindUsersRequest.offset', index=1,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='limit', full_name='org.apache.custos.iam.service.FindUsersRequest.limit', index=2,
+      number=5, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.FindUsersRequest.tenantId', index=3,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.FindUsersRequest.accessToken', index=4,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.FindUsersRequest.client_id', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.iam.service.FindUsersRequest.client_sec', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2213,
+  serialized_end=2405,
+)
+
+
+_USERSEARCHREQUEST = _descriptor.Descriptor(
+  name='UserSearchRequest',
+  full_name='org.apache.custos.iam.service.UserSearchRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='user', full_name='org.apache.custos.iam.service.UserSearchRequest.user', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.UserSearchRequest.tenantId', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.UserSearchRequest.accessToken', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.UserSearchRequest.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.iam.service.UserSearchRequest.client_sec', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.UserSearchRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2408,
+  serialized_end=2591,
+)
+
+
+_FINDUSERSRESPONSE = _descriptor.Descriptor(
+  name='FindUsersResponse',
+  full_name='org.apache.custos.iam.service.FindUsersResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.FindUsersResponse.users', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2593,
+  serialized_end=2678,
+)
+
+
+_RESETUSERPASSWORD = _descriptor.Descriptor(
+  name='ResetUserPassword',
+  full_name='org.apache.custos.iam.service.ResetUserPassword',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.ResetUserPassword.username', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='password', full_name='org.apache.custos.iam.service.ResetUserPassword.password', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.ResetUserPassword.tenantId', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.ResetUserPassword.accessToken', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.ResetUserPassword.clientId', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.ResetUserPassword.clientSec', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2681,
+  serialized_end=2812,
+)
+
+
+_DELETEUSERROLESREQUEST = _descriptor.Descriptor(
+  name='DeleteUserRolesRequest',
+  full_name='org.apache.custos.iam.service.DeleteUserRolesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.tenant_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.username', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.client_roles', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.roles', index=3,
+      number=4, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.access_token', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.client_id', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performed_by', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.performed_by', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.id', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2815,
+  serialized_end=2988,
+)
+
+
+_ADDUSERROLESREQUEST = _descriptor.Descriptor(
+  name='AddUserRolesRequest',
+  full_name='org.apache.custos.iam.service.AddUserRolesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.AddUserRolesRequest.tenant_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='usernames', full_name='org.apache.custos.iam.service.AddUserRolesRequest.usernames', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='org.apache.custos.iam.service.AddUserRolesRequest.roles', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.AddUserRolesRequest.access_token', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.AddUserRolesRequest.client_id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_level', full_name='org.apache.custos.iam.service.AddUserRolesRequest.client_level', index=5,
+      number=6, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performed_by', full_name='org.apache.custos.iam.service.AddUserRolesRequest.performed_by', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='agents', full_name='org.apache.custos.iam.service.AddUserRolesRequest.agents', index=7,
+      number=8, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2991,
+  serialized_end=3166,
+)
+
+
+_UPDATEUSERPROFILEREQUEST = _descriptor.Descriptor(
+  name='UpdateUserProfileRequest',
+  full_name='org.apache.custos.iam.service.UpdateUserProfileRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.UpdateUserProfileRequest.accessToken', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.UpdateUserProfileRequest.tenantId', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='user', full_name='org.apache.custos.iam.service.UpdateUserProfileRequest.user', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3169,
+  serialized_end=3299,
+)
+
+
+_ADDUSERRESPONSE = _descriptor.Descriptor(
+  name='AddUserResponse',
+  full_name='org.apache.custos.iam.service.AddUserResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='code', full_name='org.apache.custos.iam.service.AddUserResponse.code', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3301,
+  serialized_end=3332,
+)
+
+
+_GETOPERATIONSMETADATAREQUEST = _descriptor.Descriptor(
+  name='GetOperationsMetadataRequest',
+  full_name='org.apache.custos.iam.service.GetOperationsMetadataRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='traceId', full_name='org.apache.custos.iam.service.GetOperationsMetadataRequest.traceId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3334,
+  serialized_end=3381,
+)
+
+
+_OPERATIONMETADATA = _descriptor.Descriptor(
+  name='OperationMetadata',
+  full_name='org.apache.custos.iam.service.OperationMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='org.apache.custos.iam.service.OperationMetadata.event', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.iam.service.OperationMetadata.status', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='timeStamp', full_name='org.apache.custos.iam.service.OperationMetadata.timeStamp', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.OperationMetadata.performedBy', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3383,
+  serialized_end=3473,
+)
+
+
+_GETOPERATIONSMETADATARESPONSE = _descriptor.Descriptor(
+  name='GetOperationsMetadataResponse',
+  full_name='org.apache.custos.iam.service.GetOperationsMetadataResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.iam.service.GetOperationsMetadataResponse.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3475,
+  serialized_end=3574,
+)
+
+
+_DELETETENANTREQUEST = _descriptor.Descriptor(
+  name='DeleteTenantRequest',
+  full_name='org.apache.custos.iam.service.DeleteTenantRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.DeleteTenantRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3576,
+  serialized_end=3615,
+)
+
+
+_ADDROLESREQUEST = _descriptor.Descriptor(
+  name='AddRolesRequest',
+  full_name='org.apache.custos.iam.service.AddRolesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='org.apache.custos.iam.service.AddRolesRequest.roles', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_level', full_name='org.apache.custos.iam.service.AddRolesRequest.client_level', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.AddRolesRequest.tenant_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.AddRolesRequest.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3618,
+  serialized_end=3761,
+)
+
+
+_GETROLESREQUEST = _descriptor.Descriptor(
+  name='GetRolesRequest',
+  full_name='org.apache.custos.iam.service.GetRolesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_level', full_name='org.apache.custos.iam.service.GetRolesRequest.client_level', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.GetRolesRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.GetRolesRequest.client_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3763,
+  serialized_end=3840,
+)
+
+
+_ROLEREPRESENTATION = _descriptor.Descriptor(
+  name='RoleRepresentation',
+  full_name='org.apache.custos.iam.service.RoleRepresentation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.iam.service.RoleRepresentation.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='org.apache.custos.iam.service.RoleRepresentation.description', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='composite', full_name='org.apache.custos.iam.service.RoleRepresentation.composite', index=2,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3842,
+  serialized_end=3916,
+)
+
+
+_ALLROLES = _descriptor.Descriptor(
+  name='AllRoles',
+  full_name='org.apache.custos.iam.service.AllRoles',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='org.apache.custos.iam.service.AllRoles.roles', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.iam.service.AllRoles.scope', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3918,
+  serialized_end=4009,
+)
+
+
+_ADDPROTOCOLMAPPERREQUEST = _descriptor.Descriptor(
+  name='AddProtocolMapperRequest',
+  full_name='org.apache.custos.iam.service.AddProtocolMapperRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attribute_name', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.attribute_name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='claim_name', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.claim_name', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='claim_type', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.claim_type', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.tenant_id', index=4,
+      number=6, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.client_id', index=5,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='mapper_type', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.mapper_type', index=6,
+      number=8, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='add_to_id_token', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.add_to_id_token', index=7,
+      number=9, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='add_to_access_token', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.add_to_access_token', index=8,
+      number=10, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='add_to_user_info', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.add_to_user_info', index=9,
+      number=11, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='multi_valued', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.multi_valued', index=10,
+      number=12, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='aggregate_attribute_values', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.aggregate_attribute_values', index=11,
+      number=13, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4012,
+  serialized_end=4404,
+)
+
+
+_OPERATIONSTATUS = _descriptor.Descriptor(
+  name='OperationStatus',
+  full_name='org.apache.custos.iam.service.OperationStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.iam.service.OperationStatus.status', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4406,
+  serialized_end=4439,
+)
+
+
+_ADDUSERATTRIBUTESREQUEST = _descriptor.Descriptor(
+  name='AddUserAttributesRequest',
+  full_name='org.apache.custos.iam.service.AddUserAttributesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.attributes', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.users', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.tenant_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.access_token', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='agents', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.agents', index=6,
+      number=7, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4442,
+  serialized_end=4646,
+)
+
+
+_DELETEUSERATTRIBUTEREQUEST = _descriptor.Descriptor(
+  name='DeleteUserAttributeRequest',
+  full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.attributes', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.users', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.tenant_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.access_token', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='agents', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.agents', index=6,
+      number=7, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4649,
+  serialized_end=4855,
+)
+
+
+_USERATTRIBUTE = _descriptor.Descriptor(
+  name='UserAttribute',
+  full_name='org.apache.custos.iam.service.UserAttribute',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.iam.service.UserAttribute.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='values', full_name='org.apache.custos.iam.service.UserAttribute.values', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4857,
+  serialized_end=4901,
+)
+
+
+_EVENTPERSISTENCEREQUEST = _descriptor.Descriptor(
+  name='EventPersistenceRequest',
+  full_name='org.apache.custos.iam.service.EventPersistenceRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.EventPersistenceRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='admin_event', full_name='org.apache.custos.iam.service.EventPersistenceRequest.admin_event', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='event', full_name='org.apache.custos.iam.service.EventPersistenceRequest.event', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='enable', full_name='org.apache.custos.iam.service.EventPersistenceRequest.enable', index=3,
+      number=4, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='persistence_time', full_name='org.apache.custos.iam.service.EventPersistenceRequest.persistence_time', index=4,
+      number=5, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.EventPersistenceRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4904,
+  serialized_end=5046,
+)
+
+
+_GROUPSREQUEST = _descriptor.Descriptor(
+  name='GroupsRequest',
+  full_name='org.apache.custos.iam.service.GroupsRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.GroupsRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.GroupsRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.GroupsRequest.performedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.GroupsRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.GroupsRequest.clientSec', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='groups', full_name='org.apache.custos.iam.service.GroupsRequest.groups', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5049,
+  serialized_end=5229,
+)
+
+
+_GROUPREQUEST = _descriptor.Descriptor(
+  name='GroupRequest',
+  full_name='org.apache.custos.iam.service.GroupRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.GroupRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.GroupRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.GroupRequest.performedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.GroupRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.GroupRequest.clientSec', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.GroupRequest.id', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='group', full_name='org.apache.custos.iam.service.GroupRequest.group', index=6,
+      number=7, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5232,
+  serialized_end=5422,
+)
+
+
+_GROUPSRESPONSE = _descriptor.Descriptor(
+  name='GroupsResponse',
+  full_name='org.apache.custos.iam.service.GroupsResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='groups', full_name='org.apache.custos.iam.service.GroupsResponse.groups', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5424,
+  serialized_end=5508,
+)
+
+
+_USERGROUPMAPPINGREQUEST = _descriptor.Descriptor(
+  name='UserGroupMappingRequest',
+  full_name='org.apache.custos.iam.service.UserGroupMappingRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.performedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.clientSec', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.username', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='group_id', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.group_id', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='membership_type', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.membership_type', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5511,
+  serialized_end=5694,
+)
+
+
+_AGENTCLIENTMETADATA = _descriptor.Descriptor(
+  name='AgentClientMetadata',
+  full_name='org.apache.custos.iam.service.AgentClientMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.AgentClientMetadata.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantURL', full_name='org.apache.custos.iam.service.AgentClientMetadata.tenantURL', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='redirectURIs', full_name='org.apache.custos.iam.service.AgentClientMetadata.redirectURIs', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientName', full_name='org.apache.custos.iam.service.AgentClientMetadata.clientName', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token_life_time', full_name='org.apache.custos.iam.service.AgentClientMetadata.access_token_life_time', index=4,
+      number=5, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.AgentClientMetadata.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.AgentClientMetadata.access_token', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5697,
+  serialized_end=5872,
+)
+
+
+_AGENT = _descriptor.Descriptor(
+  name='Agent',
+  full_name='org.apache.custos.iam.service.Agent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.Agent.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='realm_roles', full_name='org.apache.custos.iam.service.Agent.realm_roles', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.Agent.attributes', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='isEnabled', full_name='org.apache.custos.iam.service.Agent.isEnabled', index=3,
+      number=4, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='creation_time', full_name='org.apache.custos.iam.service.Agent.creation_time', index=4,
+      number=5, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_modified_at', full_name='org.apache.custos.iam.service.Agent.last_modified_at', index=5,
+      number=6, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.iam.service.Agent.client_roles', index=6,
+      number=7, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5875,
+  serialized_end=6071,
+)
+
+
+_GETALLRESOURCES = _descriptor.Descriptor(
+  name='GetAllResources',
+  full_name='org.apache.custos.iam.service.GetAllResources',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.GetAllResources.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.GetAllResources.clientId', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_type', full_name='org.apache.custos.iam.service.GetAllResources.resource_type', index=2,
+      number=3, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6073,
+  serialized_end=6195,
+)
+
+
+_GETALLRESOURCESRESPONSE = _descriptor.Descriptor(
+  name='GetAllResourcesResponse',
+  full_name='org.apache.custos.iam.service.GetAllResourcesResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='agents', full_name='org.apache.custos.iam.service.GetAllResourcesResponse.agents', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.GetAllResourcesResponse.users', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6198,
+  serialized_end=6343,
+)
+
+_CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY.containing_type = _CONFIGUREFEDERATEIDPREQUEST
+_CONFIGUREFEDERATEIDPREQUEST.fields_by_name['type'].enum_type = _FEDERATEDIDPS
+_CONFIGUREFEDERATEIDPREQUEST.fields_by_name['configMap'].message_type = _CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY
+_USERREPRESENTATION.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_GROUPREPRESENTATION.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_GROUPREPRESENTATION.fields_by_name['users'].message_type = _USERREPRESENTATION
+_GROUPREPRESENTATION.fields_by_name['sub_groups'].message_type = _GROUPREPRESENTATION
+_REGISTERUSERREQUEST.fields_by_name['user'].message_type = _USERREPRESENTATION
+_REGISTERUSERSREQUEST.fields_by_name['users'].message_type = _USERREPRESENTATION
+_REGISTERUSERSRESPONSE.fields_by_name['failedUsers'].message_type = _USERREPRESENTATION
+_FINDUSERSREQUEST.fields_by_name['user'].message_type = _USERSEARCHMETADATA
+_USERSEARCHREQUEST.fields_by_name['user'].message_type = _USERSEARCHMETADATA
+_FINDUSERSRESPONSE.fields_by_name['users'].message_type = _USERREPRESENTATION
+_UPDATEUSERPROFILEREQUEST.fields_by_name['user'].message_type = _USERREPRESENTATION
+_GETOPERATIONSMETADATARESPONSE.fields_by_name['metadata'].message_type = _OPERATIONMETADATA
+_ADDROLESREQUEST.fields_by_name['roles'].message_type = _ROLEREPRESENTATION
+_ALLROLES.fields_by_name['roles'].message_type = _ROLEREPRESENTATION
+_ADDPROTOCOLMAPPERREQUEST.fields_by_name['claim_type'].enum_type = _CLAIMJSONTYPES
+_ADDPROTOCOLMAPPERREQUEST.fields_by_name['mapper_type'].enum_type = _MAPPERTYPES
+_ADDUSERATTRIBUTESREQUEST.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_DELETEUSERATTRIBUTEREQUEST.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_GROUPSREQUEST.fields_by_name['groups'].message_type = _GROUPREPRESENTATION
+_GROUPREQUEST.fields_by_name['group'].message_type = _GROUPREPRESENTATION
+_GROUPSRESPONSE.fields_by_name['groups'].message_type = _GROUPREPRESENTATION
+_AGENT.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_GETALLRESOURCES.fields_by_name['resource_type'].enum_type = _RESOURCETYPES
+_GETALLRESOURCESRESPONSE.fields_by_name['agents'].message_type = _AGENT
+_GETALLRESOURCESRESPONSE.fields_by_name['users'].message_type = _USERREPRESENTATION
+DESCRIPTOR.message_types_by_name['SetUpTenantRequest'] = _SETUPTENANTREQUEST
+DESCRIPTOR.message_types_by_name['ConfigureFederateIDPRequest'] = _CONFIGUREFEDERATEIDPREQUEST
+DESCRIPTOR.message_types_by_name['FederateIDPResponse'] = _FEDERATEIDPRESPONSE
+DESCRIPTOR.message_types_by_name['SetUpTenantResponse'] = _SETUPTENANTRESPONSE
+DESCRIPTOR.message_types_by_name['IsUsernameAvailableRequest'] = _ISUSERNAMEAVAILABLEREQUEST
+DESCRIPTOR.message_types_by_name['CheckingResponse'] = _CHECKINGRESPONSE
+DESCRIPTOR.message_types_by_name['UserRepresentation'] = _USERREPRESENTATION
+DESCRIPTOR.message_types_by_name['GroupRepresentation'] = _GROUPREPRESENTATION
+DESCRIPTOR.message_types_by_name['RegisterUserRequest'] = _REGISTERUSERREQUEST
+DESCRIPTOR.message_types_by_name['RegisterUsersRequest'] = _REGISTERUSERSREQUEST
+DESCRIPTOR.message_types_by_name['RegisterUserResponse'] = _REGISTERUSERRESPONSE
+DESCRIPTOR.message_types_by_name['RegisterUsersResponse'] = _REGISTERUSERSRESPONSE
+DESCRIPTOR.message_types_by_name['UserSearchMetadata'] = _USERSEARCHMETADATA
+DESCRIPTOR.message_types_by_name['FindUsersRequest'] = _FINDUSERSREQUEST
+DESCRIPTOR.message_types_by_name['UserSearchRequest'] = _USERSEARCHREQUEST
+DESCRIPTOR.message_types_by_name['FindUsersResponse'] = _FINDUSERSRESPONSE
+DESCRIPTOR.message_types_by_name['ResetUserPassword'] = _RESETUSERPASSWORD
+DESCRIPTOR.message_types_by_name['DeleteUserRolesRequest'] = _DELETEUSERROLESREQUEST
+DESCRIPTOR.message_types_by_name['AddUserRolesRequest'] = _ADDUSERROLESREQUEST
+DESCRIPTOR.message_types_by_name['UpdateUserProfileRequest'] = _UPDATEUSERPROFILEREQUEST
+DESCRIPTOR.message_types_by_name['AddUserResponse'] = _ADDUSERRESPONSE
+DESCRIPTOR.message_types_by_name['GetOperationsMetadataRequest'] = _GETOPERATIONSMETADATAREQUEST
+DESCRIPTOR.message_types_by_name['OperationMetadata'] = _OPERATIONMETADATA
+DESCRIPTOR.message_types_by_name['GetOperationsMetadataResponse'] = _GETOPERATIONSMETADATARESPONSE
+DESCRIPTOR.message_types_by_name['DeleteTenantRequest'] = _DELETETENANTREQUEST
+DESCRIPTOR.message_types_by_name['AddRolesRequest'] = _ADDROLESREQUEST
+DESCRIPTOR.message_types_by_name['GetRolesRequest'] = _GETROLESREQUEST
+DESCRIPTOR.message_types_by_name['RoleRepresentation'] = _ROLEREPRESENTATION
+DESCRIPTOR.message_types_by_name['AllRoles'] = _ALLROLES
+DESCRIPTOR.message_types_by_name['AddProtocolMapperRequest'] = _ADDPROTOCOLMAPPERREQUEST
+DESCRIPTOR.message_types_by_name['OperationStatus'] = _OPERATIONSTATUS
+DESCRIPTOR.message_types_by_name['AddUserAttributesRequest'] = _ADDUSERATTRIBUTESREQUEST
+DESCRIPTOR.message_types_by_name['DeleteUserAttributeRequest'] = _DELETEUSERATTRIBUTEREQUEST
+DESCRIPTOR.message_types_by_name['UserAttribute'] = _USERATTRIBUTE
+DESCRIPTOR.message_types_by_name['EventPersistenceRequest'] = _EVENTPERSISTENCEREQUEST
+DESCRIPTOR.message_types_by_name['GroupsRequest'] = _GROUPSREQUEST
+DESCRIPTOR.message_types_by_name['GroupRequest'] = _GROUPREQUEST
+DESCRIPTOR.message_types_by_name['GroupsResponse'] = _GROUPSRESPONSE
+DESCRIPTOR.message_types_by_name['UserGroupMappingRequest'] = _USERGROUPMAPPINGREQUEST
+DESCRIPTOR.message_types_by_name['AgentClientMetadata'] = _AGENTCLIENTMETADATA
+DESCRIPTOR.message_types_by_name['Agent'] = _AGENT
+DESCRIPTOR.message_types_by_name['GetAllResources'] = _GETALLRESOURCES
+DESCRIPTOR.message_types_by_name['GetAllResourcesResponse'] = _GETALLRESOURCESRESPONSE
+DESCRIPTOR.enum_types_by_name['FederatedIDPs'] = _FEDERATEDIDPS
+DESCRIPTOR.enum_types_by_name['MapperTypes'] = _MAPPERTYPES
+DESCRIPTOR.enum_types_by_name['ClaimJSONTypes'] = _CLAIMJSONTYPES
+DESCRIPTOR.enum_types_by_name['ResourceTypes'] = _RESOURCETYPES
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+SetUpTenantRequest = _reflection.GeneratedProtocolMessageType('SetUpTenantRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SETUPTENANTREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.SetUpTenantRequest)
+  })
+_sym_db.RegisterMessage(SetUpTenantRequest)
+
+ConfigureFederateIDPRequest = _reflection.GeneratedProtocolMessageType('ConfigureFederateIDPRequest', (_message.Message,), {
+
+  'ConfigMapEntry' : _reflection.GeneratedProtocolMessageType('ConfigMapEntry', (_message.Message,), {
+    'DESCRIPTOR' : _CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY,
+    '__module__' : 'IamAdminService_pb2'
+    # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry)
+    })
+  ,
+  'DESCRIPTOR' : _CONFIGUREFEDERATEIDPREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.ConfigureFederateIDPRequest)
+  })
+_sym_db.RegisterMessage(ConfigureFederateIDPRequest)
+_sym_db.RegisterMessage(ConfigureFederateIDPRequest.ConfigMapEntry)
+
+FederateIDPResponse = _reflection.GeneratedProtocolMessageType('FederateIDPResponse', (_message.Message,), {
+  'DESCRIPTOR' : _FEDERATEIDPRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.FederateIDPResponse)
+  })
+_sym_db.RegisterMessage(FederateIDPResponse)
+
+SetUpTenantResponse = _reflection.GeneratedProtocolMessageType('SetUpTenantResponse', (_message.Message,), {
+  'DESCRIPTOR' : _SETUPTENANTRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.SetUpTenantResponse)
+  })
+_sym_db.RegisterMessage(SetUpTenantResponse)
+
+IsUsernameAvailableRequest = _reflection.GeneratedProtocolMessageType('IsUsernameAvailableRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ISUSERNAMEAVAILABLEREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.IsUsernameAvailableRequest)
+  })
+_sym_db.RegisterMessage(IsUsernameAvailableRequest)
+
+CheckingResponse = _reflection.GeneratedProtocolMessageType('CheckingResponse', (_message.Message,), {
+  'DESCRIPTOR' : _CHECKINGRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.CheckingResponse)
+  })
+_sym_db.RegisterMessage(CheckingResponse)
+
+UserRepresentation = _reflection.GeneratedProtocolMessageType('UserRepresentation', (_message.Message,), {
+  'DESCRIPTOR' : _USERREPRESENTATION,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserRepresentation)
+  })
+_sym_db.RegisterMessage(UserRepresentation)
+
+GroupRepresentation = _reflection.GeneratedProtocolMessageType('GroupRepresentation', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPREPRESENTATION,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GroupRepresentation)
+  })
+_sym_db.RegisterMessage(GroupRepresentation)
+
+RegisterUserRequest = _reflection.GeneratedProtocolMessageType('RegisterUserRequest', (_message.Message,), {
+  'DESCRIPTOR' : _REGISTERUSERREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RegisterUserRequest)
+  })
+_sym_db.RegisterMessage(RegisterUserRequest)
+
+RegisterUsersRequest = _reflection.GeneratedProtocolMessageType('RegisterUsersRequest', (_message.Message,), {
+  'DESCRIPTOR' : _REGISTERUSERSREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RegisterUsersRequest)
+  })
+_sym_db.RegisterMessage(RegisterUsersRequest)
+
+RegisterUserResponse = _reflection.GeneratedProtocolMessageType('RegisterUserResponse', (_message.Message,), {
+  'DESCRIPTOR' : _REGISTERUSERRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RegisterUserResponse)
+  })
+_sym_db.RegisterMessage(RegisterUserResponse)
+
+RegisterUsersResponse = _reflection.GeneratedProtocolMessageType('RegisterUsersResponse', (_message.Message,), {
+  'DESCRIPTOR' : _REGISTERUSERSRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RegisterUsersResponse)
+  })
+_sym_db.RegisterMessage(RegisterUsersResponse)
+
+UserSearchMetadata = _reflection.GeneratedProtocolMessageType('UserSearchMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _USERSEARCHMETADATA,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserSearchMetadata)
+  })
+_sym_db.RegisterMessage(UserSearchMetadata)
+
+FindUsersRequest = _reflection.GeneratedProtocolMessageType('FindUsersRequest', (_message.Message,), {
+  'DESCRIPTOR' : _FINDUSERSREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.FindUsersRequest)
+  })
+_sym_db.RegisterMessage(FindUsersRequest)
+
+UserSearchRequest = _reflection.GeneratedProtocolMessageType('UserSearchRequest', (_message.Message,), {
+  'DESCRIPTOR' : _USERSEARCHREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserSearchRequest)
+  })
+_sym_db.RegisterMessage(UserSearchRequest)
+
+FindUsersResponse = _reflection.GeneratedProtocolMessageType('FindUsersResponse', (_message.Message,), {
+  'DESCRIPTOR' : _FINDUSERSRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.FindUsersResponse)
+  })
+_sym_db.RegisterMessage(FindUsersResponse)
+
+ResetUserPassword = _reflection.GeneratedProtocolMessageType('ResetUserPassword', (_message.Message,), {
+  'DESCRIPTOR' : _RESETUSERPASSWORD,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.ResetUserPassword)
+  })
+_sym_db.RegisterMessage(ResetUserPassword)
+
+DeleteUserRolesRequest = _reflection.GeneratedProtocolMessageType('DeleteUserRolesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETEUSERROLESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.DeleteUserRolesRequest)
+  })
+_sym_db.RegisterMessage(DeleteUserRolesRequest)
+
+AddUserRolesRequest = _reflection.GeneratedProtocolMessageType('AddUserRolesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ADDUSERROLESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddUserRolesRequest)
+  })
+_sym_db.RegisterMessage(AddUserRolesRequest)
+
+UpdateUserProfileRequest = _reflection.GeneratedProtocolMessageType('UpdateUserProfileRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATEUSERPROFILEREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UpdateUserProfileRequest)
+  })
+_sym_db.RegisterMessage(UpdateUserProfileRequest)
+
+AddUserResponse = _reflection.GeneratedProtocolMessageType('AddUserResponse', (_message.Message,), {
+  'DESCRIPTOR' : _ADDUSERRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddUserResponse)
+  })
+_sym_db.RegisterMessage(AddUserResponse)
+
+GetOperationsMetadataRequest = _reflection.GeneratedProtocolMessageType('GetOperationsMetadataRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETOPERATIONSMETADATAREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetOperationsMetadataRequest)
+  })
+_sym_db.RegisterMessage(GetOperationsMetadataRequest)
+
+OperationMetadata = _reflection.GeneratedProtocolMessageType('OperationMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _OPERATIONMETADATA,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.OperationMetadata)
+  })
+_sym_db.RegisterMessage(OperationMetadata)
+
+GetOperationsMetadataResponse = _reflection.GeneratedProtocolMessageType('GetOperationsMetadataResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETOPERATIONSMETADATARESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetOperationsMetadataResponse)
+  })
+_sym_db.RegisterMessage(GetOperationsMetadataResponse)
+
+DeleteTenantRequest = _reflection.GeneratedProtocolMessageType('DeleteTenantRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETETENANTREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.DeleteTenantRequest)
+  })
+_sym_db.RegisterMessage(DeleteTenantRequest)
+
+AddRolesRequest = _reflection.GeneratedProtocolMessageType('AddRolesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ADDROLESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddRolesRequest)
+  })
+_sym_db.RegisterMessage(AddRolesRequest)
+
+GetRolesRequest = _reflection.GeneratedProtocolMessageType('GetRolesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETROLESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetRolesRequest)
+  })
+_sym_db.RegisterMessage(GetRolesRequest)
+
+RoleRepresentation = _reflection.GeneratedProtocolMessageType('RoleRepresentation', (_message.Message,), {
+  'DESCRIPTOR' : _ROLEREPRESENTATION,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RoleRepresentation)
+  })
+_sym_db.RegisterMessage(RoleRepresentation)
+
+AllRoles = _reflection.GeneratedProtocolMessageType('AllRoles', (_message.Message,), {
+  'DESCRIPTOR' : _ALLROLES,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AllRoles)
+  })
+_sym_db.RegisterMessage(AllRoles)
+
+AddProtocolMapperRequest = _reflection.GeneratedProtocolMessageType('AddProtocolMapperRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ADDPROTOCOLMAPPERREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddProtocolMapperRequest)
+  })
+_sym_db.RegisterMessage(AddProtocolMapperRequest)
+
+OperationStatus = _reflection.GeneratedProtocolMessageType('OperationStatus', (_message.Message,), {
+  'DESCRIPTOR' : _OPERATIONSTATUS,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.OperationStatus)
+  })
+_sym_db.RegisterMessage(OperationStatus)
+
+AddUserAttributesRequest = _reflection.GeneratedProtocolMessageType('AddUserAttributesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ADDUSERATTRIBUTESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddUserAttributesRequest)
+  })
+_sym_db.RegisterMessage(AddUserAttributesRequest)
+
+DeleteUserAttributeRequest = _reflection.GeneratedProtocolMessageType('DeleteUserAttributeRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETEUSERATTRIBUTEREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.DeleteUserAttributeRequest)
+  })
+_sym_db.RegisterMessage(DeleteUserAttributeRequest)
+
+UserAttribute = _reflection.GeneratedProtocolMessageType('UserAttribute', (_message.Message,), {
+  'DESCRIPTOR' : _USERATTRIBUTE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserAttribute)
+  })
+_sym_db.RegisterMessage(UserAttribute)
+
+EventPersistenceRequest = _reflection.GeneratedProtocolMessageType('EventPersistenceRequest', (_message.Message,), {
+  'DESCRIPTOR' : _EVENTPERSISTENCEREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.EventPersistenceRequest)
+  })
+_sym_db.RegisterMessage(EventPersistenceRequest)
+
+GroupsRequest = _reflection.GeneratedProtocolMessageType('GroupsRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPSREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GroupsRequest)
+  })
+_sym_db.RegisterMessage(GroupsRequest)
+
+GroupRequest = _reflection.GeneratedProtocolMessageType('GroupRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GroupRequest)
+  })
+_sym_db.RegisterMessage(GroupRequest)
+
+GroupsResponse = _reflection.GeneratedProtocolMessageType('GroupsResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPSRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GroupsResponse)
+  })
+_sym_db.RegisterMessage(GroupsResponse)
+
+UserGroupMappingRequest = _reflection.GeneratedProtocolMessageType('UserGroupMappingRequest', (_message.Message,), {
+  'DESCRIPTOR' : _USERGROUPMAPPINGREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserGroupMappingRequest)
+  })
+_sym_db.RegisterMessage(UserGroupMappingRequest)
+
+AgentClientMetadata = _reflection.GeneratedProtocolMessageType('AgentClientMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _AGENTCLIENTMETADATA,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AgentClientMetadata)
+  })
+_sym_db.RegisterMessage(AgentClientMetadata)
+
+Agent = _reflection.GeneratedProtocolMessageType('Agent', (_message.Message,), {
+  'DESCRIPTOR' : _AGENT,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.Agent)
+  })
+_sym_db.RegisterMessage(Agent)
+
+GetAllResources = _reflection.GeneratedProtocolMessageType('GetAllResources', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLRESOURCES,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetAllResources)
+  })
+_sym_db.RegisterMessage(GetAllResources)
+
+GetAllResourcesResponse = _reflection.GeneratedProtocolMessageType('GetAllResourcesResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLRESOURCESRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetAllResourcesResponse)
+  })
+_sym_db.RegisterMessage(GetAllResourcesResponse)
+
+
+DESCRIPTOR._options = None
+_CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY._options = None
+
+_IAMADMINSERVICE = _descriptor.ServiceDescriptor(
+  name='IamAdminService',
+  full_name='org.apache.custos.iam.service.IamAdminService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=6638,
+  serialized_end=12271,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='setUPTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.setUPTenant',
+    index=0,
+    containing_service=None,
+    input_type=_SETUPTENANTREQUEST,
+    output_type=_SETUPTENANTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.updateTenant',
+    index=1,
+    containing_service=None,
+    input_type=_SETUPTENANTREQUEST,
+    output_type=_SETUPTENANTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteTenant',
+    index=2,
+    containing_service=None,
+    input_type=_DELETETENANTREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='configureFederatedIDP',
+    full_name='org.apache.custos.iam.service.IamAdminService.configureFederatedIDP',
+    index=3,
+    containing_service=None,
+    input_type=_CONFIGUREFEDERATEIDPREQUEST,
+    output_type=_FEDERATEIDPRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addRolesToTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.addRolesToTenant',
+    index=4,
+    containing_service=None,
+    input_type=_ADDROLESREQUEST,
+    output_type=_ALLROLES,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addProtocolMapper',
+    full_name='org.apache.custos.iam.service.IamAdminService.addProtocolMapper',
+    index=5,
+    containing_service=None,
+    input_type=_ADDPROTOCOLMAPPERREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getRolesOfTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.getRolesOfTenant',
+    index=6,
+    containing_service=None,
+    input_type=_GETROLESREQUEST,
+    output_type=_ALLROLES,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isUsernameAvailable',
+    full_name='org.apache.custos.iam.service.IamAdminService.isUsernameAvailable',
+    index=7,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='registerUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.registerUser',
+    index=8,
+    containing_service=None,
+    input_type=_REGISTERUSERREQUEST,
+    output_type=_REGISTERUSERRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='enableUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.enableUser',
+    index=9,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_USERREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='disableUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.disableUser',
+    index=10,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_USERREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isUserEnabled',
+    full_name='org.apache.custos.iam.service.IamAdminService.isUserEnabled',
+    index=11,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isUserExist',
+    full_name='org.apache.custos.iam.service.IamAdminService.isUserExist',
+    index=12,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_CHECKINGRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.getUser',
+    index=13,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_USERREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='findUsers',
+    full_name='org.apache.custos.iam.service.IamAdminService.findUsers',
+    index=14,
+    containing_service=None,
+    input_type=_FINDUSERSREQUEST,
+    output_type=_FINDUSERSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='resetPassword',
+    full_name='org.apache.custos.iam.service.IamAdminService.resetPassword',
+    index=15,
+    containing_service=None,
+    input_type=_RESETUSERPASSWORD,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='grantAdminPrivilege',
+    full_name='org.apache.custos.iam.service.IamAdminService.grantAdminPrivilege',
+    index=16,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeAdminPrivilege',
+    full_name='org.apache.custos.iam.service.IamAdminService.removeAdminPrivilege',
+    index=17,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='registerAndEnableUsers',
+    full_name='org.apache.custos.iam.service.IamAdminService.registerAndEnableUsers',
+    index=18,
+    containing_service=None,
+    input_type=_REGISTERUSERSREQUEST,
+    output_type=_REGISTERUSERSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addUserAttributes',
+    full_name='org.apache.custos.iam.service.IamAdminService.addUserAttributes',
+    index=19,
+    containing_service=None,
+    input_type=_ADDUSERATTRIBUTESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteUserAttributes',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteUserAttributes',
+    index=20,
+    containing_service=None,
+    input_type=_DELETEUSERATTRIBUTEREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addRolesToUsers',
+    full_name='org.apache.custos.iam.service.IamAdminService.addRolesToUsers',
+    index=21,
+    containing_service=None,
+    input_type=_ADDUSERROLESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteUser',
+    index=22,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteRolesFromUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteRolesFromUser',
+    index=23,
+    containing_service=None,
+    input_type=_DELETEUSERROLESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateUserProfile',
+    full_name='org.apache.custos.iam.service.IamAdminService.updateUserProfile',
+    index=24,
+    containing_service=None,
+    input_type=_UPDATEUSERPROFILEREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getOperationMetadata',
+    full_name='org.apache.custos.iam.service.IamAdminService.getOperationMetadata',
+    index=25,
+    containing_service=None,
+    input_type=_GETOPERATIONSMETADATAREQUEST,
+    output_type=_GETOPERATIONSMETADATARESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='configureEventPersistence',
+    full_name='org.apache.custos.iam.service.IamAdminService.configureEventPersistence',
+    index=26,
+    containing_service=None,
+    input_type=_EVENTPERSISTENCEREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createGroups',
+    full_name='org.apache.custos.iam.service.IamAdminService.createGroups',
+    index=27,
+    containing_service=None,
+    input_type=_GROUPSREQUEST,
+    output_type=_GROUPSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.updateGroup',
+    index=28,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUPREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteGroup',
+    index=29,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='findGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.findGroup',
+    index=30,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUPREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllGroups',
+    full_name='org.apache.custos.iam.service.IamAdminService.getAllGroups',
+    index=31,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUPSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addUserToGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.addUserToGroup',
+    index=32,
+    containing_service=None,
+    input_type=_USERGROUPMAPPINGREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeUserFromGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.removeUserFromGroup',
+    index=33,
+    containing_service=None,
+    input_type=_USERGROUPMAPPINGREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createAgentClient',
+    full_name='org.apache.custos.iam.service.IamAdminService.createAgentClient',
+    index=34,
+    containing_service=None,
+    input_type=_AGENTCLIENTMETADATA,
+    output_type=_SETUPTENANTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='configureAgentClient',
+    full_name='org.apache.custos.iam.service.IamAdminService.configureAgentClient',
+    index=35,
+    containing_service=None,
+    input_type=_AGENTCLIENTMETADATA,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isAgentNameAvailable',
+    full_name='org.apache.custos.iam.service.IamAdminService.isAgentNameAvailable',
+    index=36,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='registerAndEnableAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.registerAndEnableAgent',
+    index=37,
+    containing_service=None,
+    input_type=_REGISTERUSERREQUEST,
+    output_type=_REGISTERUSERRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteAgent',
+    index=38,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.getAgent',
+    index=39,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_AGENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='disableAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.disableAgent',
+    index=40,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='enableAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.enableAgent',
+    index=41,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addAgentAttributes',
+    full_name='org.apache.custos.iam.service.IamAdminService.addAgentAttributes',
+    index=42,
+    containing_service=None,
+    input_type=_ADDUSERATTRIBUTESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgentAttributes',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteAgentAttributes',
+    index=43,
+    containing_service=None,
+    input_type=_DELETEUSERATTRIBUTEREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addRolesToAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.addRolesToAgent',
+    index=44,
+    containing_service=None,
+    input_type=_ADDUSERROLESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgentRoles',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteAgentRoles',
+    index=45,
+    containing_service=None,
+    input_type=_DELETEUSERROLESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllResources',
+    full_name='org.apache.custos.iam.service.IamAdminService.getAllResources',
+    index=46,
+    containing_service=None,
+    input_type=_GETALLRESOURCES,
+    output_type=_GETALLRESOURCESRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_IAMADMINSERVICE)
+
+DESCRIPTOR.services_by_name['IamAdminService'] = _IAMADMINSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/IamAdminService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/IamAdminService_pb2_grpc.py
new file mode 100644
index 0000000..36e8812
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/IamAdminService_pb2_grpc.py
@@ -0,0 +1,1585 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import custos.server.core.IamAdminService_pb2 as IamAdminService__pb2
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+
+
+class IamAdminServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.setUPTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/setUPTenant',
+                request_serializer=IamAdminService__pb2.SetUpTenantRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.SetUpTenantResponse.FromString,
+                )
+        self.updateTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/updateTenant',
+                request_serializer=IamAdminService__pb2.SetUpTenantRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.SetUpTenantResponse.FromString,
+                )
+        self.deleteTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteTenant',
+                request_serializer=IamAdminService__pb2.DeleteTenantRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.configureFederatedIDP = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/configureFederatedIDP',
+                request_serializer=IamAdminService__pb2.ConfigureFederateIDPRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.FederateIDPResponse.FromString,
+                )
+        self.addRolesToTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addRolesToTenant',
+                request_serializer=IamAdminService__pb2.AddRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.AllRoles.FromString,
+                )
+        self.addProtocolMapper = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addProtocolMapper',
+                request_serializer=IamAdminService__pb2.AddProtocolMapperRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getRolesOfTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getRolesOfTenant',
+                request_serializer=IamAdminService__pb2.GetRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.AllRoles.FromString,
+                )
+        self.isUsernameAvailable = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/isUsernameAvailable',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.registerUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/registerUser',
+                request_serializer=IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.RegisterUserResponse.FromString,
+                )
+        self.enableUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/enableUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.UserRepresentation.FromString,
+                )
+        self.disableUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/disableUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.UserRepresentation.FromString,
+                )
+        self.isUserEnabled = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/isUserEnabled',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.isUserExist = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/isUserExist',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.CheckingResponse.FromString,
+                )
+        self.getUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.UserRepresentation.FromString,
+                )
+        self.findUsers = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/findUsers',
+                request_serializer=IamAdminService__pb2.FindUsersRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.FindUsersResponse.FromString,
+                )
+        self.resetPassword = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/resetPassword',
+                request_serializer=IamAdminService__pb2.ResetUserPassword.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.grantAdminPrivilege = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/grantAdminPrivilege',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.removeAdminPrivilege = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/removeAdminPrivilege',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.registerAndEnableUsers = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/registerAndEnableUsers',
+                request_serializer=IamAdminService__pb2.RegisterUsersRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.RegisterUsersResponse.FromString,
+                )
+        self.addUserAttributes = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addUserAttributes',
+                request_serializer=IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteUserAttributes = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteUserAttributes',
+                request_serializer=IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.addRolesToUsers = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addRolesToUsers',
+                request_serializer=IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteRolesFromUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteRolesFromUser',
+                request_serializer=IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.updateUserProfile = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/updateUserProfile',
+                request_serializer=IamAdminService__pb2.UpdateUserProfileRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getOperationMetadata = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getOperationMetadata',
+                request_serializer=IamAdminService__pb2.GetOperationsMetadataRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GetOperationsMetadataResponse.FromString,
+                )
+        self.configureEventPersistence = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/configureEventPersistence',
+                request_serializer=IamAdminService__pb2.EventPersistenceRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.createGroups = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/createGroups',
+                request_serializer=IamAdminService__pb2.GroupsRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupsResponse.FromString,
+                )
+        self.updateGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/updateGroup',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupRepresentation.FromString,
+                )
+        self.deleteGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteGroup',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.findGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/findGroup',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupRepresentation.FromString,
+                )
+        self.getAllGroups = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getAllGroups',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupsResponse.FromString,
+                )
+        self.addUserToGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addUserToGroup',
+                request_serializer=IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.removeUserFromGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/removeUserFromGroup',
+                request_serializer=IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.createAgentClient = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/createAgentClient',
+                request_serializer=IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+                response_deserializer=IamAdminService__pb2.SetUpTenantResponse.FromString,
+                )
+        self.configureAgentClient = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/configureAgentClient',
+                request_serializer=IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.isAgentNameAvailable = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/isAgentNameAvailable',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.registerAndEnableAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/registerAndEnableAgent',
+                request_serializer=IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.RegisterUserResponse.FromString,
+                )
+        self.deleteAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteAgent',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getAgent',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.Agent.FromString,
+                )
+        self.disableAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/disableAgent',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.enableAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/enableAgent',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.addAgentAttributes = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addAgentAttributes',
+                request_serializer=IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteAgentAttributes = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteAgentAttributes',
+                request_serializer=IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.addRolesToAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addRolesToAgent',
+                request_serializer=IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteAgentRoles = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteAgentRoles',
+                request_serializer=IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getAllResources = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getAllResources',
+                request_serializer=IamAdminService__pb2.GetAllResources.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GetAllResourcesResponse.FromString,
+                )
+
+
+class IamAdminServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def setUPTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def configureFederatedIDP(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addRolesToTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addProtocolMapper(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getRolesOfTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isUsernameAvailable(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def registerUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def enableUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def disableUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isUserEnabled(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isUserExist(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def findUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def resetPassword(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def grantAdminPrivilege(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeAdminPrivilege(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def registerAndEnableUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addUserAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteUserAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addRolesToUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteRolesFromUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getOperationMetadata(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def configureEventPersistence(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def createGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def findGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addUserToGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeUserFromGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def createAgentClient(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def configureAgentClient(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isAgentNameAvailable(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def registerAndEnableAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def disableAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def enableAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addAgentAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteAgentAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addRolesToAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteAgentRoles(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllResources(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_IamAdminServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'setUPTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.setUPTenant,
+                    request_deserializer=IamAdminService__pb2.SetUpTenantRequest.FromString,
+                    response_serializer=IamAdminService__pb2.SetUpTenantResponse.SerializeToString,
+            ),
+            'updateTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateTenant,
+                    request_deserializer=IamAdminService__pb2.SetUpTenantRequest.FromString,
+                    response_serializer=IamAdminService__pb2.SetUpTenantResponse.SerializeToString,
+            ),
+            'deleteTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteTenant,
+                    request_deserializer=IamAdminService__pb2.DeleteTenantRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'configureFederatedIDP': grpc.unary_unary_rpc_method_handler(
+                    servicer.configureFederatedIDP,
+                    request_deserializer=IamAdminService__pb2.ConfigureFederateIDPRequest.FromString,
+                    response_serializer=IamAdminService__pb2.FederateIDPResponse.SerializeToString,
+            ),
+            'addRolesToTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.addRolesToTenant,
+                    request_deserializer=IamAdminService__pb2.AddRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.AllRoles.SerializeToString,
+            ),
+            'addProtocolMapper': grpc.unary_unary_rpc_method_handler(
+                    servicer.addProtocolMapper,
+                    request_deserializer=IamAdminService__pb2.AddProtocolMapperRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getRolesOfTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.getRolesOfTenant,
+                    request_deserializer=IamAdminService__pb2.GetRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.AllRoles.SerializeToString,
+            ),
+            'isUsernameAvailable': grpc.unary_unary_rpc_method_handler(
+                    servicer.isUsernameAvailable,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'registerUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.registerUser,
+                    request_deserializer=IamAdminService__pb2.RegisterUserRequest.FromString,
+                    response_serializer=IamAdminService__pb2.RegisterUserResponse.SerializeToString,
+            ),
+            'enableUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.enableUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.UserRepresentation.SerializeToString,
+            ),
+            'disableUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.disableUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.UserRepresentation.SerializeToString,
+            ),
+            'isUserEnabled': grpc.unary_unary_rpc_method_handler(
+                    servicer.isUserEnabled,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'isUserExist': grpc.unary_unary_rpc_method_handler(
+                    servicer.isUserExist,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.CheckingResponse.SerializeToString,
+            ),
+            'getUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.getUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.UserRepresentation.SerializeToString,
+            ),
+            'findUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.findUsers,
+                    request_deserializer=IamAdminService__pb2.FindUsersRequest.FromString,
+                    response_serializer=IamAdminService__pb2.FindUsersResponse.SerializeToString,
+            ),
+            'resetPassword': grpc.unary_unary_rpc_method_handler(
+                    servicer.resetPassword,
+                    request_deserializer=IamAdminService__pb2.ResetUserPassword.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'grantAdminPrivilege': grpc.unary_unary_rpc_method_handler(
+                    servicer.grantAdminPrivilege,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'removeAdminPrivilege': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeAdminPrivilege,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'registerAndEnableUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.registerAndEnableUsers,
+                    request_deserializer=IamAdminService__pb2.RegisterUsersRequest.FromString,
+                    response_serializer=IamAdminService__pb2.RegisterUsersResponse.SerializeToString,
+            ),
+            'addUserAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.addUserAttributes,
+                    request_deserializer=IamAdminService__pb2.AddUserAttributesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteUserAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteUserAttributes,
+                    request_deserializer=IamAdminService__pb2.DeleteUserAttributeRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'addRolesToUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.addRolesToUsers,
+                    request_deserializer=IamAdminService__pb2.AddUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteRolesFromUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteRolesFromUser,
+                    request_deserializer=IamAdminService__pb2.DeleteUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'updateUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateUserProfile,
+                    request_deserializer=IamAdminService__pb2.UpdateUserProfileRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getOperationMetadata': grpc.unary_unary_rpc_method_handler(
+                    servicer.getOperationMetadata,
+                    request_deserializer=IamAdminService__pb2.GetOperationsMetadataRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GetOperationsMetadataResponse.SerializeToString,
+            ),
+            'configureEventPersistence': grpc.unary_unary_rpc_method_handler(
+                    servicer.configureEventPersistence,
+                    request_deserializer=IamAdminService__pb2.EventPersistenceRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'createGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.createGroups,
+                    request_deserializer=IamAdminService__pb2.GroupsRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupsResponse.SerializeToString,
+            ),
+            'updateGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateGroup,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupRepresentation.SerializeToString,
+            ),
+            'deleteGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteGroup,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'findGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.findGroup,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupRepresentation.SerializeToString,
+            ),
+            'getAllGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllGroups,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupsResponse.SerializeToString,
+            ),
+            'addUserToGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.addUserToGroup,
+                    request_deserializer=IamAdminService__pb2.UserGroupMappingRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'removeUserFromGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeUserFromGroup,
+                    request_deserializer=IamAdminService__pb2.UserGroupMappingRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'createAgentClient': grpc.unary_unary_rpc_method_handler(
+                    servicer.createAgentClient,
+                    request_deserializer=IamAdminService__pb2.AgentClientMetadata.FromString,
+                    response_serializer=IamAdminService__pb2.SetUpTenantResponse.SerializeToString,
+            ),
+            'configureAgentClient': grpc.unary_unary_rpc_method_handler(
+                    servicer.configureAgentClient,
+                    request_deserializer=IamAdminService__pb2.AgentClientMetadata.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'isAgentNameAvailable': grpc.unary_unary_rpc_method_handler(
+                    servicer.isAgentNameAvailable,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'registerAndEnableAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.registerAndEnableAgent,
+                    request_deserializer=IamAdminService__pb2.RegisterUserRequest.FromString,
+                    response_serializer=IamAdminService__pb2.RegisterUserResponse.SerializeToString,
+            ),
+            'deleteAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteAgent,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAgent,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.Agent.SerializeToString,
+            ),
+            'disableAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.disableAgent,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'enableAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.enableAgent,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'addAgentAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.addAgentAttributes,
+                    request_deserializer=IamAdminService__pb2.AddUserAttributesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteAgentAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteAgentAttributes,
+                    request_deserializer=IamAdminService__pb2.DeleteUserAttributeRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'addRolesToAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.addRolesToAgent,
+                    request_deserializer=IamAdminService__pb2.AddUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteAgentRoles': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteAgentRoles,
+                    request_deserializer=IamAdminService__pb2.DeleteUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getAllResources': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllResources,
+                    request_deserializer=IamAdminService__pb2.GetAllResources.FromString,
+                    response_serializer=IamAdminService__pb2.GetAllResourcesResponse.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'org.apache.custos.iam.service.IamAdminService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class IamAdminService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def setUPTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/setUPTenant',
+            IamAdminService__pb2.SetUpTenantRequest.SerializeToString,
+            IamAdminService__pb2.SetUpTenantResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/updateTenant',
+            IamAdminService__pb2.SetUpTenantRequest.SerializeToString,
+            IamAdminService__pb2.SetUpTenantResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteTenant',
+            IamAdminService__pb2.DeleteTenantRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def configureFederatedIDP(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/configureFederatedIDP',
+            IamAdminService__pb2.ConfigureFederateIDPRequest.SerializeToString,
+            IamAdminService__pb2.FederateIDPResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addRolesToTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addRolesToTenant',
+            IamAdminService__pb2.AddRolesRequest.SerializeToString,
+            IamAdminService__pb2.AllRoles.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addProtocolMapper(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addProtocolMapper',
+            IamAdminService__pb2.AddProtocolMapperRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getRolesOfTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getRolesOfTenant',
+            IamAdminService__pb2.GetRolesRequest.SerializeToString,
+            IamAdminService__pb2.AllRoles.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isUsernameAvailable(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/isUsernameAvailable',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def registerUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/registerUser',
+            IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+            IamAdminService__pb2.RegisterUserResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def enableUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/enableUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.UserRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def disableUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/disableUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.UserRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isUserEnabled(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/isUserEnabled',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isUserExist(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/isUserExist',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.CheckingResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.UserRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def findUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/findUsers',
+            IamAdminService__pb2.FindUsersRequest.SerializeToString,
+            IamAdminService__pb2.FindUsersResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def resetPassword(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/resetPassword',
+            IamAdminService__pb2.ResetUserPassword.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def grantAdminPrivilege(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/grantAdminPrivilege',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeAdminPrivilege(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/removeAdminPrivilege',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def registerAndEnableUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/registerAndEnableUsers',
+            IamAdminService__pb2.RegisterUsersRequest.SerializeToString,
+            IamAdminService__pb2.RegisterUsersResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addUserAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addUserAttributes',
+            IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteUserAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteUserAttributes',
+            IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addRolesToUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addRolesToUsers',
+            IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteRolesFromUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteRolesFromUser',
+            IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/updateUserProfile',
+            IamAdminService__pb2.UpdateUserProfileRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getOperationMetadata(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getOperationMetadata',
+            IamAdminService__pb2.GetOperationsMetadataRequest.SerializeToString,
+            IamAdminService__pb2.GetOperationsMetadataResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def configureEventPersistence(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/configureEventPersistence',
+            IamAdminService__pb2.EventPersistenceRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def createGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/createGroups',
+            IamAdminService__pb2.GroupsRequest.SerializeToString,
+            IamAdminService__pb2.GroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/updateGroup',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.GroupRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteGroup',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def findGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/findGroup',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.GroupRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getAllGroups',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.GroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addUserToGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addUserToGroup',
+            IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeUserFromGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/removeUserFromGroup',
+            IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def createAgentClient(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/createAgentClient',
+            IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+            IamAdminService__pb2.SetUpTenantResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def configureAgentClient(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/configureAgentClient',
+            IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isAgentNameAvailable(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/isAgentNameAvailable',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def registerAndEnableAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/registerAndEnableAgent',
+            IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+            IamAdminService__pb2.RegisterUserResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteAgent',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getAgent',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.Agent.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def disableAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/disableAgent',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def enableAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/enableAgent',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addAgentAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addAgentAttributes',
+            IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteAgentAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteAgentAttributes',
+            IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addRolesToAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addRolesToAgent',
+            IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteAgentRoles(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteAgentRoles',
+            IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllResources(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getAllResources',
+            IamAdminService__pb2.GetAllResources.SerializeToString,
+            IamAdminService__pb2.GetAllResourcesResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/IdentityService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/IdentityService_pb2.py
new file mode 100644
index 0000000..fced1b5
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/IdentityService_pb2.py
@@ -0,0 +1,945 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: IdentityService.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='IdentityService.proto',
+  package='org.apache.custos.identity.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n\x15IdentityService.proto\x12\"org.apache.custos.identity.service\x1a\x1cgoogle/protobuf/struct.proto\"[\n\tAuthToken\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x01 \x01(\t\x12\x39\n\x06\x63laims\x18\x02 \x03(\x0b\x32).org.apache.custos.identity.service.Claim\"#\n\x05\x43laim\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"r\n\x04User\x12\x0b\n\x03sub\x18\x01 \x01(\t\x12\x10\n\x08\x66ullName\x18\x02 \x01(\t\x12\x11\n\tfirstName\x18\x03 \x01(\t\x12\x10\n\x08lastName\x18\x04 \x01(\t\x12\x14\n\x0c\x65mailAddress\x18\x05 \x01(\t\x12\x10\n\x08username\x18\x06 \x01(\t\"\xc1\x01\n\x0fGetTokenRequest\x12\x11\n\ttenant_id\x18\x01 \x01(\x03\x12\x11\n\tclient_id\x18\x02 \x01(\t\x12\x15\n\rclient_secret\x18\x03 \x01(\t\x12\x14\n\x0credirect_uri\x18\x04 \x01(\t\x12\x0c\n\x04\x63ode\x18\x06 \x01(\t\x12\x10\n\x08username\x18\x07 \x01(\t\x12\x10\n\x08password\x18\x08 \x01(\t\x12\x15\n\rrefresh_token\x18\t \x01(\t\x12\x12\n\ngrant_type\x18\n \x01(\t\"\xd3\x01\n\rTokenResponse\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x01 \x01(\t\x12\x12\n\nexpires_in\x18\x02 \x01(\x01\x12\x1a\n\x12refresh_expires_in\x18\x03 \x01(\x01\x12\x15\n\rrefresh_token\x18\x04 \x01(\t\x12\x12\n\ntoken_type\x18\x05 \x01(\t\x12\x10\n\x08id_token\x18\x06 \x01(\t\x12\x19\n\x11not_before_policy\x18\x07 \x01(\x01\x12\x15\n\rsession_state\x18\x08 \x01(\t\x12\r\n\x05scope\x18\t \x01(\t\"u\n\x15\x41uthenticationRequest\x12\x10\n\x08\x63lientId\x18\x01 \x01(\t\x12\x14\n\x0c\x63lientSecret\x18\x02 \x01(\t\x12\x10\n\x08tenantId\x18\x03 \x01(\x03\x12\x10\n\x08username\x18\x04 \x01(\t\x12\x10\n\x08password\x18\x05 \x01(\t\"/\n\x16IsAuthenticateResponse\x12\x15\n\rauthenticated\x18\x01 \x01(\x08\"[\n\x1fGetUserManagementSATokenRequest\x12\x10\n\x08\x63lientId\x18\x01 \x01(\t\x12\x14\n\x0c\x63lientSecret\x18\x02 \x01(\t\x12\x10\n\x08tenantId\x18\x03 \x01(\x03\"3\n\x1fGetAuthorizationEndpointRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\"6\n\x15\x41uthorizationResponse\x12\x1d\n\x15\x61uthorizationEndpoint\x18\x02 \x01(\t\"S\n\x14GetOIDCConfiguration\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x15\n\rclient_secret\x18\x02 \x01(\t\x12\x11\n\ttenant_id\x18\x03 \x01(\x03\"M\n\x0eGetJWKSRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x15\n\rclient_secret\x18\x02 \x01(\t\x12\x11\n\ttenant_id\x18\x03 \x01(\x03\"g\n\x11\x45ndSessionRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x15\n\rclient_secret\x18\x02 \x01(\t\x12\x11\n\ttenant_id\x18\x03 \x01(\x03\x12\x15\n\rrefresh_token\x18\x04 \x01(\t\"!\n\x0fOperationStatus\x12\x0e\n\x06status\x18\x01 \x01(\x08\x32\x9d\n\n\x0fIdentityService\x12x\n\x0c\x61uthenticate\x12\x39.org.apache.custos.identity.service.AuthenticationRequest\x1a-.org.apache.custos.identity.service.AuthToken\x12{\n\x0eisAuthenticate\x12-.org.apache.custos.identity.service.AuthToken\x1a:.org.apache.custos.identity.service.IsAuthenticateResponse\x12\x62\n\x07getUser\x12-.org.apache.custos.identity.service.AuthToken\x1a(.org.apache.custos.identity.service.User\x12\xa0\x01\n*getUserManagementServiceAccountAccessToken\x12\x43.org.apache.custos.identity.service.GetUserManagementSATokenRequest\x1a-.org.apache.custos.identity.service.AuthToken\x12X\n\x08getToken\x12\x33.org.apache.custos.identity.service.GetTokenRequest\x1a\x17.google.protobuf.Struct\x12\x96\x01\n\x14getAuthorizeEndpoint\x12\x43.org.apache.custos.identity.service.GetAuthorizationEndpointRequest\x1a\x39.org.apache.custos.identity.service.AuthorizationResponse\x12i\n\x14getOIDCConfiguration\x12\x38.org.apache.custos.identity.service.GetOIDCConfiguration\x1a\x17.google.protobuf.Struct\x12k\n\x1bgetTokenByPasswordGrantType\x12\x33.org.apache.custos.identity.service.GetTokenRequest\x1a\x17.google.protobuf.Struct\x12o\n\x1fgetTokenByRefreshTokenGrantType\x12\x33.org.apache.custos.identity.service.GetTokenRequest\x1a\x17.google.protobuf.Struct\x12V\n\x07getJWKS\x12\x32.org.apache.custos.identity.service.GetJWKSRequest\x1a\x17.google.protobuf.Struct\x12x\n\nendSession\x12\x35.org.apache.custos.identity.service.EndSessionRequest\x1a\x33.org.apache.custos.identity.service.OperationStatusB\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,])
+
+
+
+
+_AUTHTOKEN = _descriptor.Descriptor(
+  name='AuthToken',
+  full_name='org.apache.custos.identity.service.AuthToken',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.identity.service.AuthToken.accessToken', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='claims', full_name='org.apache.custos.identity.service.AuthToken.claims', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=91,
+  serialized_end=182,
+)
+
+
+_CLAIM = _descriptor.Descriptor(
+  name='Claim',
+  full_name='org.apache.custos.identity.service.Claim',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.identity.service.Claim.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.identity.service.Claim.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=184,
+  serialized_end=219,
+)
+
+
+_USER = _descriptor.Descriptor(
+  name='User',
+  full_name='org.apache.custos.identity.service.User',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='sub', full_name='org.apache.custos.identity.service.User.sub', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='fullName', full_name='org.apache.custos.identity.service.User.fullName', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='firstName', full_name='org.apache.custos.identity.service.User.firstName', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='lastName', full_name='org.apache.custos.identity.service.User.lastName', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='emailAddress', full_name='org.apache.custos.identity.service.User.emailAddress', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.identity.service.User.username', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=221,
+  serialized_end=335,
+)
+
+
+_GETTOKENREQUEST = _descriptor.Descriptor(
+  name='GetTokenRequest',
+  full_name='org.apache.custos.identity.service.GetTokenRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.identity.service.GetTokenRequest.tenant_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.identity.service.GetTokenRequest.client_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_secret', full_name='org.apache.custos.identity.service.GetTokenRequest.client_secret', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='redirect_uri', full_name='org.apache.custos.identity.service.GetTokenRequest.redirect_uri', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='code', full_name='org.apache.custos.identity.service.GetTokenRequest.code', index=4,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.identity.service.GetTokenRequest.username', index=5,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='password', full_name='org.apache.custos.identity.service.GetTokenRequest.password', index=6,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='refresh_token', full_name='org.apache.custos.identity.service.GetTokenRequest.refresh_token', index=7,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='grant_type', full_name='org.apache.custos.identity.service.GetTokenRequest.grant_type', index=8,
+      number=10, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=338,
+  serialized_end=531,
+)
+
+
+_TOKENRESPONSE = _descriptor.Descriptor(
+  name='TokenResponse',
+  full_name='org.apache.custos.identity.service.TokenResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.identity.service.TokenResponse.access_token', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='expires_in', full_name='org.apache.custos.identity.service.TokenResponse.expires_in', index=1,
+      number=2, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='refresh_expires_in', full_name='org.apache.custos.identity.service.TokenResponse.refresh_expires_in', index=2,
+      number=3, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='refresh_token', full_name='org.apache.custos.identity.service.TokenResponse.refresh_token', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='token_type', full_name='org.apache.custos.identity.service.TokenResponse.token_type', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='id_token', full_name='org.apache.custos.identity.service.TokenResponse.id_token', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='not_before_policy', full_name='org.apache.custos.identity.service.TokenResponse.not_before_policy', index=6,
+      number=7, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='session_state', full_name='org.apache.custos.identity.service.TokenResponse.session_state', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.identity.service.TokenResponse.scope', index=8,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=534,
+  serialized_end=745,
+)
+
+
+_AUTHENTICATIONREQUEST = _descriptor.Descriptor(
+  name='AuthenticationRequest',
+  full_name='org.apache.custos.identity.service.AuthenticationRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.identity.service.AuthenticationRequest.clientId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientSecret', full_name='org.apache.custos.identity.service.AuthenticationRequest.clientSecret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.identity.service.AuthenticationRequest.tenantId', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.identity.service.AuthenticationRequest.username', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='password', full_name='org.apache.custos.identity.service.AuthenticationRequest.password', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=747,
+  serialized_end=864,
+)
+
+
+_ISAUTHENTICATERESPONSE = _descriptor.Descriptor(
+  name='IsAuthenticateResponse',
+  full_name='org.apache.custos.identity.service.IsAuthenticateResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='authenticated', full_name='org.apache.custos.identity.service.IsAuthenticateResponse.authenticated', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=866,
+  serialized_end=913,
+)
+
+
+_GETUSERMANAGEMENTSATOKENREQUEST = _descriptor.Descriptor(
+  name='GetUserManagementSATokenRequest',
+  full_name='org.apache.custos.identity.service.GetUserManagementSATokenRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.identity.service.GetUserManagementSATokenRequest.clientId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientSecret', full_name='org.apache.custos.identity.service.GetUserManagementSATokenRequest.clientSecret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.identity.service.GetUserManagementSATokenRequest.tenantId', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=915,
+  serialized_end=1006,
+)
+
+
+_GETAUTHORIZATIONENDPOINTREQUEST = _descriptor.Descriptor(
+  name='GetAuthorizationEndpointRequest',
+  full_name='org.apache.custos.identity.service.GetAuthorizationEndpointRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.identity.service.GetAuthorizationEndpointRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1008,
+  serialized_end=1059,
+)
+
+
+_AUTHORIZATIONRESPONSE = _descriptor.Descriptor(
+  name='AuthorizationResponse',
+  full_name='org.apache.custos.identity.service.AuthorizationResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='authorizationEndpoint', full_name='org.apache.custos.identity.service.AuthorizationResponse.authorizationEndpoint', index=0,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1061,
+  serialized_end=1115,
+)
+
+
+_GETOIDCCONFIGURATION = _descriptor.Descriptor(
+  name='GetOIDCConfiguration',
+  full_name='org.apache.custos.identity.service.GetOIDCConfiguration',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.identity.service.GetOIDCConfiguration.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_secret', full_name='org.apache.custos.identity.service.GetOIDCConfiguration.client_secret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.identity.service.GetOIDCConfiguration.tenant_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1117,
+  serialized_end=1200,
+)
+
+
+_GETJWKSREQUEST = _descriptor.Descriptor(
+  name='GetJWKSRequest',
+  full_name='org.apache.custos.identity.service.GetJWKSRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.identity.service.GetJWKSRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_secret', full_name='org.apache.custos.identity.service.GetJWKSRequest.client_secret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.identity.service.GetJWKSRequest.tenant_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1202,
+  serialized_end=1279,
+)
+
+
+_ENDSESSIONREQUEST = _descriptor.Descriptor(
+  name='EndSessionRequest',
+  full_name='org.apache.custos.identity.service.EndSessionRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.identity.service.EndSessionRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_secret', full_name='org.apache.custos.identity.service.EndSessionRequest.client_secret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.identity.service.EndSessionRequest.tenant_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='refresh_token', full_name='org.apache.custos.identity.service.EndSessionRequest.refresh_token', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1281,
+  serialized_end=1384,
+)
+
+
+_OPERATIONSTATUS = _descriptor.Descriptor(
+  name='OperationStatus',
+  full_name='org.apache.custos.identity.service.OperationStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.identity.service.OperationStatus.status', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1386,
+  serialized_end=1419,
+)
+
+_AUTHTOKEN.fields_by_name['claims'].message_type = _CLAIM
+DESCRIPTOR.message_types_by_name['AuthToken'] = _AUTHTOKEN
+DESCRIPTOR.message_types_by_name['Claim'] = _CLAIM
+DESCRIPTOR.message_types_by_name['User'] = _USER
+DESCRIPTOR.message_types_by_name['GetTokenRequest'] = _GETTOKENREQUEST
+DESCRIPTOR.message_types_by_name['TokenResponse'] = _TOKENRESPONSE
+DESCRIPTOR.message_types_by_name['AuthenticationRequest'] = _AUTHENTICATIONREQUEST
+DESCRIPTOR.message_types_by_name['IsAuthenticateResponse'] = _ISAUTHENTICATERESPONSE
+DESCRIPTOR.message_types_by_name['GetUserManagementSATokenRequest'] = _GETUSERMANAGEMENTSATOKENREQUEST
+DESCRIPTOR.message_types_by_name['GetAuthorizationEndpointRequest'] = _GETAUTHORIZATIONENDPOINTREQUEST
+DESCRIPTOR.message_types_by_name['AuthorizationResponse'] = _AUTHORIZATIONRESPONSE
+DESCRIPTOR.message_types_by_name['GetOIDCConfiguration'] = _GETOIDCCONFIGURATION
+DESCRIPTOR.message_types_by_name['GetJWKSRequest'] = _GETJWKSREQUEST
+DESCRIPTOR.message_types_by_name['EndSessionRequest'] = _ENDSESSIONREQUEST
+DESCRIPTOR.message_types_by_name['OperationStatus'] = _OPERATIONSTATUS
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+AuthToken = _reflection.GeneratedProtocolMessageType('AuthToken', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHTOKEN,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.AuthToken)
+  })
+_sym_db.RegisterMessage(AuthToken)
+
+Claim = _reflection.GeneratedProtocolMessageType('Claim', (_message.Message,), {
+  'DESCRIPTOR' : _CLAIM,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.Claim)
+  })
+_sym_db.RegisterMessage(Claim)
+
+User = _reflection.GeneratedProtocolMessageType('User', (_message.Message,), {
+  'DESCRIPTOR' : _USER,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.User)
+  })
+_sym_db.RegisterMessage(User)
+
+GetTokenRequest = _reflection.GeneratedProtocolMessageType('GetTokenRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETTOKENREQUEST,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.GetTokenRequest)
+  })
+_sym_db.RegisterMessage(GetTokenRequest)
+
+TokenResponse = _reflection.GeneratedProtocolMessageType('TokenResponse', (_message.Message,), {
+  'DESCRIPTOR' : _TOKENRESPONSE,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.TokenResponse)
+  })
+_sym_db.RegisterMessage(TokenResponse)
+
+AuthenticationRequest = _reflection.GeneratedProtocolMessageType('AuthenticationRequest', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHENTICATIONREQUEST,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.AuthenticationRequest)
+  })
+_sym_db.RegisterMessage(AuthenticationRequest)
+
+IsAuthenticateResponse = _reflection.GeneratedProtocolMessageType('IsAuthenticateResponse', (_message.Message,), {
+  'DESCRIPTOR' : _ISAUTHENTICATERESPONSE,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.IsAuthenticateResponse)
+  })
+_sym_db.RegisterMessage(IsAuthenticateResponse)
+
+GetUserManagementSATokenRequest = _reflection.GeneratedProtocolMessageType('GetUserManagementSATokenRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETUSERMANAGEMENTSATOKENREQUEST,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.GetUserManagementSATokenRequest)
+  })
+_sym_db.RegisterMessage(GetUserManagementSATokenRequest)
+
+GetAuthorizationEndpointRequest = _reflection.GeneratedProtocolMessageType('GetAuthorizationEndpointRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETAUTHORIZATIONENDPOINTREQUEST,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.GetAuthorizationEndpointRequest)
+  })
+_sym_db.RegisterMessage(GetAuthorizationEndpointRequest)
+
+AuthorizationResponse = _reflection.GeneratedProtocolMessageType('AuthorizationResponse', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHORIZATIONRESPONSE,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.AuthorizationResponse)
+  })
+_sym_db.RegisterMessage(AuthorizationResponse)
+
+GetOIDCConfiguration = _reflection.GeneratedProtocolMessageType('GetOIDCConfiguration', (_message.Message,), {
+  'DESCRIPTOR' : _GETOIDCCONFIGURATION,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.GetOIDCConfiguration)
+  })
+_sym_db.RegisterMessage(GetOIDCConfiguration)
+
+GetJWKSRequest = _reflection.GeneratedProtocolMessageType('GetJWKSRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETJWKSREQUEST,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.GetJWKSRequest)
+  })
+_sym_db.RegisterMessage(GetJWKSRequest)
+
+EndSessionRequest = _reflection.GeneratedProtocolMessageType('EndSessionRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ENDSESSIONREQUEST,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.EndSessionRequest)
+  })
+_sym_db.RegisterMessage(EndSessionRequest)
+
+OperationStatus = _reflection.GeneratedProtocolMessageType('OperationStatus', (_message.Message,), {
+  'DESCRIPTOR' : _OPERATIONSTATUS,
+  '__module__' : 'IdentityService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.service.OperationStatus)
+  })
+_sym_db.RegisterMessage(OperationStatus)
+
+
+DESCRIPTOR._options = None
+
+_IDENTITYSERVICE = _descriptor.ServiceDescriptor(
+  name='IdentityService',
+  full_name='org.apache.custos.identity.service.IdentityService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=1422,
+  serialized_end=2731,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='authenticate',
+    full_name='org.apache.custos.identity.service.IdentityService.authenticate',
+    index=0,
+    containing_service=None,
+    input_type=_AUTHENTICATIONREQUEST,
+    output_type=_AUTHTOKEN,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isAuthenticate',
+    full_name='org.apache.custos.identity.service.IdentityService.isAuthenticate',
+    index=1,
+    containing_service=None,
+    input_type=_AUTHTOKEN,
+    output_type=_ISAUTHENTICATERESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUser',
+    full_name='org.apache.custos.identity.service.IdentityService.getUser',
+    index=2,
+    containing_service=None,
+    input_type=_AUTHTOKEN,
+    output_type=_USER,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUserManagementServiceAccountAccessToken',
+    full_name='org.apache.custos.identity.service.IdentityService.getUserManagementServiceAccountAccessToken',
+    index=3,
+    containing_service=None,
+    input_type=_GETUSERMANAGEMENTSATOKENREQUEST,
+    output_type=_AUTHTOKEN,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getToken',
+    full_name='org.apache.custos.identity.service.IdentityService.getToken',
+    index=4,
+    containing_service=None,
+    input_type=_GETTOKENREQUEST,
+    output_type=google_dot_protobuf_dot_struct__pb2._STRUCT,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAuthorizeEndpoint',
+    full_name='org.apache.custos.identity.service.IdentityService.getAuthorizeEndpoint',
+    index=5,
+    containing_service=None,
+    input_type=_GETAUTHORIZATIONENDPOINTREQUEST,
+    output_type=_AUTHORIZATIONRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getOIDCConfiguration',
+    full_name='org.apache.custos.identity.service.IdentityService.getOIDCConfiguration',
+    index=6,
+    containing_service=None,
+    input_type=_GETOIDCCONFIGURATION,
+    output_type=google_dot_protobuf_dot_struct__pb2._STRUCT,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getTokenByPasswordGrantType',
+    full_name='org.apache.custos.identity.service.IdentityService.getTokenByPasswordGrantType',
+    index=7,
+    containing_service=None,
+    input_type=_GETTOKENREQUEST,
+    output_type=google_dot_protobuf_dot_struct__pb2._STRUCT,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getTokenByRefreshTokenGrantType',
+    full_name='org.apache.custos.identity.service.IdentityService.getTokenByRefreshTokenGrantType',
+    index=8,
+    containing_service=None,
+    input_type=_GETTOKENREQUEST,
+    output_type=google_dot_protobuf_dot_struct__pb2._STRUCT,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getJWKS',
+    full_name='org.apache.custos.identity.service.IdentityService.getJWKS',
+    index=9,
+    containing_service=None,
+    input_type=_GETJWKSREQUEST,
+    output_type=google_dot_protobuf_dot_struct__pb2._STRUCT,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='endSession',
+    full_name='org.apache.custos.identity.service.IdentityService.endSession',
+    index=10,
+    containing_service=None,
+    input_type=_ENDSESSIONREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_IDENTITYSERVICE)
+
+DESCRIPTOR.services_by_name['IdentityService'] = _IDENTITYSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/IdentityService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/IdentityService_pb2_grpc.py
new file mode 100644
index 0000000..7fb16ae
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/IdentityService_pb2_grpc.py
@@ -0,0 +1,217 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import IdentityService_pb2 as IdentityService__pb2
+from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
+
+
+class IdentityServiceStub(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.authenticate = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/authenticate',
+        request_serializer=IdentityService__pb2.AuthenticationRequest.SerializeToString,
+        response_deserializer=IdentityService__pb2.AuthToken.FromString,
+        )
+    self.isAuthenticate = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/isAuthenticate',
+        request_serializer=IdentityService__pb2.AuthToken.SerializeToString,
+        response_deserializer=IdentityService__pb2.IsAuthenticateResponse.FromString,
+        )
+    self.getUser = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/getUser',
+        request_serializer=IdentityService__pb2.AuthToken.SerializeToString,
+        response_deserializer=IdentityService__pb2.User.FromString,
+        )
+    self.getUserManagementServiceAccountAccessToken = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/getUserManagementServiceAccountAccessToken',
+        request_serializer=IdentityService__pb2.GetUserManagementSATokenRequest.SerializeToString,
+        response_deserializer=IdentityService__pb2.AuthToken.FromString,
+        )
+    self.getToken = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/getToken',
+        request_serializer=IdentityService__pb2.GetTokenRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+        )
+    self.getAuthorizeEndpoint = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/getAuthorizeEndpoint',
+        request_serializer=IdentityService__pb2.GetAuthorizationEndpointRequest.SerializeToString,
+        response_deserializer=IdentityService__pb2.AuthorizationResponse.FromString,
+        )
+    self.getOIDCConfiguration = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/getOIDCConfiguration',
+        request_serializer=IdentityService__pb2.GetOIDCConfiguration.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+        )
+    self.getTokenByPasswordGrantType = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/getTokenByPasswordGrantType',
+        request_serializer=IdentityService__pb2.GetTokenRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+        )
+    self.getTokenByRefreshTokenGrantType = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/getTokenByRefreshTokenGrantType',
+        request_serializer=IdentityService__pb2.GetTokenRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+        )
+    self.getJWKS = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/getJWKS',
+        request_serializer=IdentityService__pb2.GetJWKSRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+        )
+    self.endSession = channel.unary_unary(
+        '/org.apache.custos.identity.service.IdentityService/endSession',
+        request_serializer=IdentityService__pb2.EndSessionRequest.SerializeToString,
+        response_deserializer=IdentityService__pb2.OperationStatus.FromString,
+        )
+
+
+class IdentityServiceServicer(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def authenticate(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def isAuthenticate(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getUser(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getUserManagementServiceAccountAccessToken(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getToken(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAuthorizeEndpoint(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getOIDCConfiguration(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getTokenByPasswordGrantType(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getTokenByRefreshTokenGrantType(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getJWKS(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def endSession(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_IdentityServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'authenticate': grpc.unary_unary_rpc_method_handler(
+          servicer.authenticate,
+          request_deserializer=IdentityService__pb2.AuthenticationRequest.FromString,
+          response_serializer=IdentityService__pb2.AuthToken.SerializeToString,
+      ),
+      'isAuthenticate': grpc.unary_unary_rpc_method_handler(
+          servicer.isAuthenticate,
+          request_deserializer=IdentityService__pb2.AuthToken.FromString,
+          response_serializer=IdentityService__pb2.IsAuthenticateResponse.SerializeToString,
+      ),
+      'getUser': grpc.unary_unary_rpc_method_handler(
+          servicer.getUser,
+          request_deserializer=IdentityService__pb2.AuthToken.FromString,
+          response_serializer=IdentityService__pb2.User.SerializeToString,
+      ),
+      'getUserManagementServiceAccountAccessToken': grpc.unary_unary_rpc_method_handler(
+          servicer.getUserManagementServiceAccountAccessToken,
+          request_deserializer=IdentityService__pb2.GetUserManagementSATokenRequest.FromString,
+          response_serializer=IdentityService__pb2.AuthToken.SerializeToString,
+      ),
+      'getToken': grpc.unary_unary_rpc_method_handler(
+          servicer.getToken,
+          request_deserializer=IdentityService__pb2.GetTokenRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_struct__pb2.Struct.SerializeToString,
+      ),
+      'getAuthorizeEndpoint': grpc.unary_unary_rpc_method_handler(
+          servicer.getAuthorizeEndpoint,
+          request_deserializer=IdentityService__pb2.GetAuthorizationEndpointRequest.FromString,
+          response_serializer=IdentityService__pb2.AuthorizationResponse.SerializeToString,
+      ),
+      'getOIDCConfiguration': grpc.unary_unary_rpc_method_handler(
+          servicer.getOIDCConfiguration,
+          request_deserializer=IdentityService__pb2.GetOIDCConfiguration.FromString,
+          response_serializer=google_dot_protobuf_dot_struct__pb2.Struct.SerializeToString,
+      ),
+      'getTokenByPasswordGrantType': grpc.unary_unary_rpc_method_handler(
+          servicer.getTokenByPasswordGrantType,
+          request_deserializer=IdentityService__pb2.GetTokenRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_struct__pb2.Struct.SerializeToString,
+      ),
+      'getTokenByRefreshTokenGrantType': grpc.unary_unary_rpc_method_handler(
+          servicer.getTokenByRefreshTokenGrantType,
+          request_deserializer=IdentityService__pb2.GetTokenRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_struct__pb2.Struct.SerializeToString,
+      ),
+      'getJWKS': grpc.unary_unary_rpc_method_handler(
+          servicer.getJWKS,
+          request_deserializer=IdentityService__pb2.GetJWKSRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_struct__pb2.Struct.SerializeToString,
+      ),
+      'endSession': grpc.unary_unary_rpc_method_handler(
+          servicer.endSession,
+          request_deserializer=IdentityService__pb2.EndSessionRequest.FromString,
+          response_serializer=IdentityService__pb2.OperationStatus.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.custos.identity.service.IdentityService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/ResourceSecretService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/ResourceSecretService_pb2.py
new file mode 100644
index 0000000..ab90d68
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/ResourceSecretService_pb2.py
@@ -0,0 +1,948 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: ResourceSecretService.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='ResourceSecretService.proto',
+  package='org.apache.custos.resource.secret.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x1bResourceSecretService.proto\x12)org.apache.custos.resource.secret.service\"\xda\x03\n\x0eSecretMetadata\x12P\n\nowner_type\x18\x01 \x01(\x0e\x32<.org.apache.custos.resource.secret.service.ResourceOwnerType\x12N\n\rresource_type\x18\x02 \x01(\x0e\x32\x37.org.apache.custos.resource.secret.service.ResourceType\x12I\n\x06source\x18\x03 \x01(\x0e\x32\x39.org.apache.custos.resource.secret.service.ResourceSource\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\r\n\x05value\x18\x05 \x01(\t\x12K\n\x04type\x18\x06 \x01(\x0e\x32=.org.apache.custos.resource.secret.service.ResourceSecretType\x12\x10\n\x08tenantId\x18\x07 \x01(\x03\x12\x10\n\x08owner_id\x18\x08 \x01(\t\x12\x16\n\x0epersisted_time\x18\t \x01(\x03\x12\r\n\x05token\x18\n \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x0b \x01(\t\x12\x11\n\tclient_id\x18\x0c \x01(\t\"\xab\x01\n\x10GetSecretRequest\x12K\n\x08metadata\x18\x01 \x01(\x0b\x32\x39.org.apache.custos.resource.secret.service.SecretMetadata\x12\x10\n\x08tenantId\x18\x02 \x01(\x03\x12\x10\n\x08\x63lientId\x18\x03 \x01(\t\x12\x11\n\tclientSec\x18\x04 \x01(\t\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x05 \x01(\t\"\xc6\x01\n\x15\x43\x65rtificateCredential\x12K\n\x08metadata\x18\x01 \x01(\x0b\x32\x39.org.apache.custos.resource.secret.service.SecretMetadata\x12\x11\n\tx509_cert\x18\x03 \x01(\t\x12\x11\n\tnot_after\x18\x04 \x01(\t\x12\x13\n\x0bprivate_key\x18\x05 \x01(\t\x12\x11\n\tlife_time\x18\x06 \x01(\x03\x12\x12\n\nnot_before\x18\x07 \x01(\t\"s\n\x12PasswordCredential\x12K\n\x08metadata\x18\x01 \x01(\x0b\x32\x39.org.apache.custos.resource.secret.service.SecretMetadata\x12\x10\n\x08password\x18\x03 \x01(\t\"\x99\x01\n\rSSHCredential\x12K\n\x08metadata\x18\x01 \x01(\x0b\x32\x39.org.apache.custos.resource.secret.service.SecretMetadata\x12\x12\n\npassphrase\x18\x03 \x01(\t\x12\x12\n\npublic_key\x18\x04 \x01(\t\x12\x13\n\x0bprivate_key\x18\x05 \x01(\t\"o\n#GetResourceCredentialByTokenRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\r\n\x05token\x18\x02 \x01(\t\x12\x14\n\x0cperformed_by\x18\x03 \x01(\t\x12\x11\n\tclient_id\x18\x04 \x01(\t\"\xd3\x01\n%GetResourceCredentialSummariesRequest\x12\x45\n\x04type\x18\x01 \x01(\x0e\x32\x37.org.apache.custos.resource.secret.service.ResourceType\x12\x19\n\x11\x61\x63\x63\x65ssible_tokens\x18\x02 \x03(\t\x12\x10\n\x08tenantId\x18\x03 \x01(\x03\x12\x10\n\x08owner_id\x18\x04 \x01(\t\x12\x11\n\tall_types\x18\x05 \x01(\x08\x12\x11\n\tclient_id\x18\x06 \x01(\t\"j\n\x1bResourceCredentialSummaries\x12K\n\x08metadata\x18\x01 \x03(\x0b\x32\x39.org.apache.custos.resource.secret.service.SecretMetadata\".\n\x1d\x41\x64\x64ResourceCredentialResponse\x12\r\n\x05token\x18\x01 \x01(\t\"3\n!ResourceCredentialOperationStatus\x12\x0e\n\x06status\x18\x01 \x01(\x08*<\n\x11ResourceOwnerType\x12\x0f\n\x0bTENANT_USER\x10\x00\x12\n\n\x06\x43USTOS\x10\x01\x12\n\n\x06TENANT\x10\x02*Y\n\x0cResourceType\x12\x16\n\x12SERVER_CERTIFICATE\x10\x00\x12\x1b\n\x17JWT_SIGNING_CERTIFICATE\x10\x01\x12\x14\n\x10VAULT_CREDENTIAL\x10\x02*D\n\x0eResourceSource\x12\x08\n\x04KUBE\x10\x00\x12\t\n\x05LOCAL\x10\x01\x12\x0c\n\x08\x45XTERNAL\x10\x02\x12\x0f\n\x0bLETSENCRYPT\x10\x03*A\n\x12ResourceSecretType\x12\x07\n\x03SSH\x10\x00\x12\x0c\n\x08PASSWORD\x10\x01\x12\x14\n\x10X509_CERTIFICATE\x10\x02\x32\x8f\x10\n\x15ResourceSecretService\x12\x83\x01\n\tgetSecret\x12;.org.apache.custos.resource.secret.service.GetSecretRequest\x1a\x39.org.apache.custos.resource.secret.service.SecretMetadata\x12\xa9\x01\n\x1cgetResourceCredentialSummary\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1a\x39.org.apache.custos.resource.secret.service.SecretMetadata\x12\xbd\x01\n!getAllResourceCredentialSummaries\x12P.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest\x1a\x46.org.apache.custos.resource.secret.service.ResourceCredentialSummaries\x12\x96\x01\n\x10\x61\x64\x64SSHCredential\x12\x38.org.apache.custos.resource.secret.service.SSHCredential\x1aH.org.apache.custos.resource.secret.service.AddResourceCredentialResponse\x12\xa0\x01\n\x15\x61\x64\x64PasswordCredential\x12=.org.apache.custos.resource.secret.service.PasswordCredential\x1aH.org.apache.custos.resource.secret.service.AddResourceCredentialResponse\x12\xa6\x01\n\x18\x61\x64\x64\x43\x65rtificateCredential\x12@.org.apache.custos.resource.secret.service.CertificateCredential\x1aH.org.apache.custos.resource.secret.service.AddResourceCredentialResponse\x12\x9c\x01\n\x10getSSHCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1a\x38.org.apache.custos.resource.secret.service.SSHCredential\x12\xa6\x01\n\x15getPasswordCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1a=.org.apache.custos.resource.secret.service.PasswordCredential\x12\xac\x01\n\x18getCertificateCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1a@.org.apache.custos.resource.secret.service.CertificateCredential\x12\xb3\x01\n\x13\x64\x65leteSSHCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1aL.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus\x12\xb3\x01\n\x13\x64\x65letePWDCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1aL.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus\x12\xbb\x01\n\x1b\x64\x65leteCertificateCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1aL.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatusB\x02P\x01\x62\x06proto3'
+)
+
+_RESOURCEOWNERTYPE = _descriptor.EnumDescriptor(
+  name='ResourceOwnerType',
+  full_name='org.apache.custos.resource.secret.service.ResourceOwnerType',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='TENANT_USER', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CUSTOS', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='TENANT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=1735,
+  serialized_end=1795,
+)
+_sym_db.RegisterEnumDescriptor(_RESOURCEOWNERTYPE)
+
+ResourceOwnerType = enum_type_wrapper.EnumTypeWrapper(_RESOURCEOWNERTYPE)
+_RESOURCETYPE = _descriptor.EnumDescriptor(
+  name='ResourceType',
+  full_name='org.apache.custos.resource.secret.service.ResourceType',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVER_CERTIFICATE', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='JWT_SIGNING_CERTIFICATE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='VAULT_CREDENTIAL', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=1797,
+  serialized_end=1886,
+)
+_sym_db.RegisterEnumDescriptor(_RESOURCETYPE)
+
+ResourceType = enum_type_wrapper.EnumTypeWrapper(_RESOURCETYPE)
+_RESOURCESOURCE = _descriptor.EnumDescriptor(
+  name='ResourceSource',
+  full_name='org.apache.custos.resource.secret.service.ResourceSource',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='KUBE', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='LOCAL', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EXTERNAL', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='LETSENCRYPT', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=1888,
+  serialized_end=1956,
+)
+_sym_db.RegisterEnumDescriptor(_RESOURCESOURCE)
+
+ResourceSource = enum_type_wrapper.EnumTypeWrapper(_RESOURCESOURCE)
+_RESOURCESECRETTYPE = _descriptor.EnumDescriptor(
+  name='ResourceSecretType',
+  full_name='org.apache.custos.resource.secret.service.ResourceSecretType',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SSH', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='PASSWORD', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='X509_CERTIFICATE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=1958,
+  serialized_end=2023,
+)
+_sym_db.RegisterEnumDescriptor(_RESOURCESECRETTYPE)
+
+ResourceSecretType = enum_type_wrapper.EnumTypeWrapper(_RESOURCESECRETTYPE)
+TENANT_USER = 0
+CUSTOS = 1
+TENANT = 2
+SERVER_CERTIFICATE = 0
+JWT_SIGNING_CERTIFICATE = 1
+VAULT_CREDENTIAL = 2
+KUBE = 0
+LOCAL = 1
+EXTERNAL = 2
+LETSENCRYPT = 3
+SSH = 0
+PASSWORD = 1
+X509_CERTIFICATE = 2
+
+
+
+_SECRETMETADATA = _descriptor.Descriptor(
+  name='SecretMetadata',
+  full_name='org.apache.custos.resource.secret.service.SecretMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='owner_type', full_name='org.apache.custos.resource.secret.service.SecretMetadata.owner_type', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_type', full_name='org.apache.custos.resource.secret.service.SecretMetadata.resource_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='source', full_name='org.apache.custos.resource.secret.service.SecretMetadata.source', index=2,
+      number=3, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.resource.secret.service.SecretMetadata.name', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.resource.secret.service.SecretMetadata.value', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.resource.secret.service.SecretMetadata.type', index=5,
+      number=6, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.resource.secret.service.SecretMetadata.tenantId', index=6,
+      number=7, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='owner_id', full_name='org.apache.custos.resource.secret.service.SecretMetadata.owner_id', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='persisted_time', full_name='org.apache.custos.resource.secret.service.SecretMetadata.persisted_time', index=8,
+      number=9, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='token', full_name='org.apache.custos.resource.secret.service.SecretMetadata.token', index=9,
+      number=10, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='org.apache.custos.resource.secret.service.SecretMetadata.description', index=10,
+      number=11, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.resource.secret.service.SecretMetadata.client_id', index=11,
+      number=12, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=75,
+  serialized_end=549,
+)
+
+
+_GETSECRETREQUEST = _descriptor.Descriptor(
+  name='GetSecretRequest',
+  full_name='org.apache.custos.resource.secret.service.GetSecretRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.resource.secret.service.GetSecretRequest.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.resource.secret.service.GetSecretRequest.tenantId', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.resource.secret.service.GetSecretRequest.clientId', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.resource.secret.service.GetSecretRequest.clientSec', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.resource.secret.service.GetSecretRequest.accessToken', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=552,
+  serialized_end=723,
+)
+
+
+_CERTIFICATECREDENTIAL = _descriptor.Descriptor(
+  name='CertificateCredential',
+  full_name='org.apache.custos.resource.secret.service.CertificateCredential',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.resource.secret.service.CertificateCredential.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='x509_cert', full_name='org.apache.custos.resource.secret.service.CertificateCredential.x509_cert', index=1,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='not_after', full_name='org.apache.custos.resource.secret.service.CertificateCredential.not_after', index=2,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='private_key', full_name='org.apache.custos.resource.secret.service.CertificateCredential.private_key', index=3,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='life_time', full_name='org.apache.custos.resource.secret.service.CertificateCredential.life_time', index=4,
+      number=6, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='not_before', full_name='org.apache.custos.resource.secret.service.CertificateCredential.not_before', index=5,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=726,
+  serialized_end=924,
+)
+
+
+_PASSWORDCREDENTIAL = _descriptor.Descriptor(
+  name='PasswordCredential',
+  full_name='org.apache.custos.resource.secret.service.PasswordCredential',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.resource.secret.service.PasswordCredential.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='password', full_name='org.apache.custos.resource.secret.service.PasswordCredential.password', index=1,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=926,
+  serialized_end=1041,
+)
+
+
+_SSHCREDENTIAL = _descriptor.Descriptor(
+  name='SSHCredential',
+  full_name='org.apache.custos.resource.secret.service.SSHCredential',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.resource.secret.service.SSHCredential.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='passphrase', full_name='org.apache.custos.resource.secret.service.SSHCredential.passphrase', index=1,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='public_key', full_name='org.apache.custos.resource.secret.service.SSHCredential.public_key', index=2,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='private_key', full_name='org.apache.custos.resource.secret.service.SSHCredential.private_key', index=3,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1044,
+  serialized_end=1197,
+)
+
+
+_GETRESOURCECREDENTIALBYTOKENREQUEST = _descriptor.Descriptor(
+  name='GetResourceCredentialByTokenRequest',
+  full_name='org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='token', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.token', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performed_by', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.performed_by', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1199,
+  serialized_end=1310,
+)
+
+
+_GETRESOURCECREDENTIALSUMMARIESREQUEST = _descriptor.Descriptor(
+  name='GetResourceCredentialSummariesRequest',
+  full_name='org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.type', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessible_tokens', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.accessible_tokens', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.tenantId', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='owner_id', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.owner_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='all_types', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.all_types', index=4,
+      number=5, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest.client_id', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1313,
+  serialized_end=1524,
+)
+
+
+_RESOURCECREDENTIALSUMMARIES = _descriptor.Descriptor(
+  name='ResourceCredentialSummaries',
+  full_name='org.apache.custos.resource.secret.service.ResourceCredentialSummaries',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.resource.secret.service.ResourceCredentialSummaries.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1526,
+  serialized_end=1632,
+)
+
+
+_ADDRESOURCECREDENTIALRESPONSE = _descriptor.Descriptor(
+  name='AddResourceCredentialResponse',
+  full_name='org.apache.custos.resource.secret.service.AddResourceCredentialResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='token', full_name='org.apache.custos.resource.secret.service.AddResourceCredentialResponse.token', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1634,
+  serialized_end=1680,
+)
+
+
+_RESOURCECREDENTIALOPERATIONSTATUS = _descriptor.Descriptor(
+  name='ResourceCredentialOperationStatus',
+  full_name='org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus.status', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1682,
+  serialized_end=1733,
+)
+
+_SECRETMETADATA.fields_by_name['owner_type'].enum_type = _RESOURCEOWNERTYPE
+_SECRETMETADATA.fields_by_name['resource_type'].enum_type = _RESOURCETYPE
+_SECRETMETADATA.fields_by_name['source'].enum_type = _RESOURCESOURCE
+_SECRETMETADATA.fields_by_name['type'].enum_type = _RESOURCESECRETTYPE
+_GETSECRETREQUEST.fields_by_name['metadata'].message_type = _SECRETMETADATA
+_CERTIFICATECREDENTIAL.fields_by_name['metadata'].message_type = _SECRETMETADATA
+_PASSWORDCREDENTIAL.fields_by_name['metadata'].message_type = _SECRETMETADATA
+_SSHCREDENTIAL.fields_by_name['metadata'].message_type = _SECRETMETADATA
+_GETRESOURCECREDENTIALSUMMARIESREQUEST.fields_by_name['type'].enum_type = _RESOURCETYPE
+_RESOURCECREDENTIALSUMMARIES.fields_by_name['metadata'].message_type = _SECRETMETADATA
+DESCRIPTOR.message_types_by_name['SecretMetadata'] = _SECRETMETADATA
+DESCRIPTOR.message_types_by_name['GetSecretRequest'] = _GETSECRETREQUEST
+DESCRIPTOR.message_types_by_name['CertificateCredential'] = _CERTIFICATECREDENTIAL
+DESCRIPTOR.message_types_by_name['PasswordCredential'] = _PASSWORDCREDENTIAL
+DESCRIPTOR.message_types_by_name['SSHCredential'] = _SSHCREDENTIAL
+DESCRIPTOR.message_types_by_name['GetResourceCredentialByTokenRequest'] = _GETRESOURCECREDENTIALBYTOKENREQUEST
+DESCRIPTOR.message_types_by_name['GetResourceCredentialSummariesRequest'] = _GETRESOURCECREDENTIALSUMMARIESREQUEST
+DESCRIPTOR.message_types_by_name['ResourceCredentialSummaries'] = _RESOURCECREDENTIALSUMMARIES
+DESCRIPTOR.message_types_by_name['AddResourceCredentialResponse'] = _ADDRESOURCECREDENTIALRESPONSE
+DESCRIPTOR.message_types_by_name['ResourceCredentialOperationStatus'] = _RESOURCECREDENTIALOPERATIONSTATUS
+DESCRIPTOR.enum_types_by_name['ResourceOwnerType'] = _RESOURCEOWNERTYPE
+DESCRIPTOR.enum_types_by_name['ResourceType'] = _RESOURCETYPE
+DESCRIPTOR.enum_types_by_name['ResourceSource'] = _RESOURCESOURCE
+DESCRIPTOR.enum_types_by_name['ResourceSecretType'] = _RESOURCESECRETTYPE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+SecretMetadata = _reflection.GeneratedProtocolMessageType('SecretMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _SECRETMETADATA,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.SecretMetadata)
+  })
+_sym_db.RegisterMessage(SecretMetadata)
+
+GetSecretRequest = _reflection.GeneratedProtocolMessageType('GetSecretRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETSECRETREQUEST,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.GetSecretRequest)
+  })
+_sym_db.RegisterMessage(GetSecretRequest)
+
+CertificateCredential = _reflection.GeneratedProtocolMessageType('CertificateCredential', (_message.Message,), {
+  'DESCRIPTOR' : _CERTIFICATECREDENTIAL,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.CertificateCredential)
+  })
+_sym_db.RegisterMessage(CertificateCredential)
+
+PasswordCredential = _reflection.GeneratedProtocolMessageType('PasswordCredential', (_message.Message,), {
+  'DESCRIPTOR' : _PASSWORDCREDENTIAL,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.PasswordCredential)
+  })
+_sym_db.RegisterMessage(PasswordCredential)
+
+SSHCredential = _reflection.GeneratedProtocolMessageType('SSHCredential', (_message.Message,), {
+  'DESCRIPTOR' : _SSHCREDENTIAL,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.SSHCredential)
+  })
+_sym_db.RegisterMessage(SSHCredential)
+
+GetResourceCredentialByTokenRequest = _reflection.GeneratedProtocolMessageType('GetResourceCredentialByTokenRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETRESOURCECREDENTIALBYTOKENREQUEST,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest)
+  })
+_sym_db.RegisterMessage(GetResourceCredentialByTokenRequest)
+
+GetResourceCredentialSummariesRequest = _reflection.GeneratedProtocolMessageType('GetResourceCredentialSummariesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETRESOURCECREDENTIALSUMMARIESREQUEST,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest)
+  })
+_sym_db.RegisterMessage(GetResourceCredentialSummariesRequest)
+
+ResourceCredentialSummaries = _reflection.GeneratedProtocolMessageType('ResourceCredentialSummaries', (_message.Message,), {
+  'DESCRIPTOR' : _RESOURCECREDENTIALSUMMARIES,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.ResourceCredentialSummaries)
+  })
+_sym_db.RegisterMessage(ResourceCredentialSummaries)
+
+AddResourceCredentialResponse = _reflection.GeneratedProtocolMessageType('AddResourceCredentialResponse', (_message.Message,), {
+  'DESCRIPTOR' : _ADDRESOURCECREDENTIALRESPONSE,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.AddResourceCredentialResponse)
+  })
+_sym_db.RegisterMessage(AddResourceCredentialResponse)
+
+ResourceCredentialOperationStatus = _reflection.GeneratedProtocolMessageType('ResourceCredentialOperationStatus', (_message.Message,), {
+  'DESCRIPTOR' : _RESOURCECREDENTIALOPERATIONSTATUS,
+  '__module__' : 'ResourceSecretService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus)
+  })
+_sym_db.RegisterMessage(ResourceCredentialOperationStatus)
+
+
+DESCRIPTOR._options = None
+
+_RESOURCESECRETSERVICE = _descriptor.ServiceDescriptor(
+  name='ResourceSecretService',
+  full_name='org.apache.custos.resource.secret.service.ResourceSecretService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=2026,
+  serialized_end=4089,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='getSecret',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.getSecret',
+    index=0,
+    containing_service=None,
+    input_type=_GETSECRETREQUEST,
+    output_type=_SECRETMETADATA,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getResourceCredentialSummary',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.getResourceCredentialSummary',
+    index=1,
+    containing_service=None,
+    input_type=_GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=_SECRETMETADATA,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllResourceCredentialSummaries',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.getAllResourceCredentialSummaries',
+    index=2,
+    containing_service=None,
+    input_type=_GETRESOURCECREDENTIALSUMMARIESREQUEST,
+    output_type=_RESOURCECREDENTIALSUMMARIES,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addSSHCredential',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.addSSHCredential',
+    index=3,
+    containing_service=None,
+    input_type=_SSHCREDENTIAL,
+    output_type=_ADDRESOURCECREDENTIALRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addPasswordCredential',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.addPasswordCredential',
+    index=4,
+    containing_service=None,
+    input_type=_PASSWORDCREDENTIAL,
+    output_type=_ADDRESOURCECREDENTIALRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addCertificateCredential',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.addCertificateCredential',
+    index=5,
+    containing_service=None,
+    input_type=_CERTIFICATECREDENTIAL,
+    output_type=_ADDRESOURCECREDENTIALRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getSSHCredential',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.getSSHCredential',
+    index=6,
+    containing_service=None,
+    input_type=_GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=_SSHCREDENTIAL,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getPasswordCredential',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.getPasswordCredential',
+    index=7,
+    containing_service=None,
+    input_type=_GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=_PASSWORDCREDENTIAL,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getCertificateCredential',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.getCertificateCredential',
+    index=8,
+    containing_service=None,
+    input_type=_GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=_CERTIFICATECREDENTIAL,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteSSHCredential',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.deleteSSHCredential',
+    index=9,
+    containing_service=None,
+    input_type=_GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=_RESOURCECREDENTIALOPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deletePWDCredential',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.deletePWDCredential',
+    index=10,
+    containing_service=None,
+    input_type=_GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=_RESOURCECREDENTIALOPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteCertificateCredential',
+    full_name='org.apache.custos.resource.secret.service.ResourceSecretService.deleteCertificateCredential',
+    index=11,
+    containing_service=None,
+    input_type=_GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=_RESOURCECREDENTIALOPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_RESOURCESECRETSERVICE)
+
+DESCRIPTOR.services_by_name['ResourceSecretService'] = _RESOURCESECRETSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/ResourceSecretService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/ResourceSecretService_pb2_grpc.py
new file mode 100644
index 0000000..cb8bef3
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/ResourceSecretService_pb2_grpc.py
@@ -0,0 +1,429 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import ResourceSecretService_pb2 as ResourceSecretService__pb2
+
+
+class ResourceSecretServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.getSecret = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/getSecret',
+                request_serializer=ResourceSecretService__pb2.GetSecretRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.SecretMetadata.FromString,
+                )
+        self.getResourceCredentialSummary = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/getResourceCredentialSummary',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.SecretMetadata.FromString,
+                )
+        self.getAllResourceCredentialSummaries = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/getAllResourceCredentialSummaries',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialSummariesRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.ResourceCredentialSummaries.FromString,
+                )
+        self.addSSHCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/addSSHCredential',
+                request_serializer=ResourceSecretService__pb2.SSHCredential.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+                )
+        self.addPasswordCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/addPasswordCredential',
+                request_serializer=ResourceSecretService__pb2.PasswordCredential.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+                )
+        self.addCertificateCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/addCertificateCredential',
+                request_serializer=ResourceSecretService__pb2.CertificateCredential.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+                )
+        self.getSSHCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/getSSHCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.SSHCredential.FromString,
+                )
+        self.getPasswordCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/getPasswordCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.PasswordCredential.FromString,
+                )
+        self.getCertificateCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/getCertificateCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.CertificateCredential.FromString,
+                )
+        self.deleteSSHCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/deleteSSHCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+                )
+        self.deletePWDCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/deletePWDCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+                )
+        self.deleteCertificateCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.service.ResourceSecretService/deleteCertificateCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+                )
+
+
+class ResourceSecretServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def getSecret(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getResourceCredentialSummary(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllResourceCredentialSummaries(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addSSHCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addPasswordCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addCertificateCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getSSHCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getPasswordCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getCertificateCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteSSHCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deletePWDCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteCertificateCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_ResourceSecretServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'getSecret': grpc.unary_unary_rpc_method_handler(
+                    servicer.getSecret,
+                    request_deserializer=ResourceSecretService__pb2.GetSecretRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.SecretMetadata.SerializeToString,
+            ),
+            'getResourceCredentialSummary': grpc.unary_unary_rpc_method_handler(
+                    servicer.getResourceCredentialSummary,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.SecretMetadata.SerializeToString,
+            ),
+            'getAllResourceCredentialSummaries': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllResourceCredentialSummaries,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialSummariesRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.ResourceCredentialSummaries.SerializeToString,
+            ),
+            'addSSHCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.addSSHCredential,
+                    request_deserializer=ResourceSecretService__pb2.SSHCredential.FromString,
+                    response_serializer=ResourceSecretService__pb2.AddResourceCredentialResponse.SerializeToString,
+            ),
+            'addPasswordCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.addPasswordCredential,
+                    request_deserializer=ResourceSecretService__pb2.PasswordCredential.FromString,
+                    response_serializer=ResourceSecretService__pb2.AddResourceCredentialResponse.SerializeToString,
+            ),
+            'addCertificateCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.addCertificateCredential,
+                    request_deserializer=ResourceSecretService__pb2.CertificateCredential.FromString,
+                    response_serializer=ResourceSecretService__pb2.AddResourceCredentialResponse.SerializeToString,
+            ),
+            'getSSHCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.getSSHCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.SSHCredential.SerializeToString,
+            ),
+            'getPasswordCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.getPasswordCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.PasswordCredential.SerializeToString,
+            ),
+            'getCertificateCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.getCertificateCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.CertificateCredential.SerializeToString,
+            ),
+            'deleteSSHCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteSSHCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.SerializeToString,
+            ),
+            'deletePWDCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.deletePWDCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.SerializeToString,
+            ),
+            'deleteCertificateCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteCertificateCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'org.apache.custos.resource.secret.service.ResourceSecretService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class ResourceSecretService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def getSecret(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/getSecret',
+            ResourceSecretService__pb2.GetSecretRequest.SerializeToString,
+            ResourceSecretService__pb2.SecretMetadata.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getResourceCredentialSummary(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/getResourceCredentialSummary',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.SecretMetadata.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllResourceCredentialSummaries(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/getAllResourceCredentialSummaries',
+            ResourceSecretService__pb2.GetResourceCredentialSummariesRequest.SerializeToString,
+            ResourceSecretService__pb2.ResourceCredentialSummaries.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addSSHCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/addSSHCredential',
+            ResourceSecretService__pb2.SSHCredential.SerializeToString,
+            ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addPasswordCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/addPasswordCredential',
+            ResourceSecretService__pb2.PasswordCredential.SerializeToString,
+            ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addCertificateCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/addCertificateCredential',
+            ResourceSecretService__pb2.CertificateCredential.SerializeToString,
+            ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getSSHCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/getSSHCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.SSHCredential.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getPasswordCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/getPasswordCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.PasswordCredential.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getCertificateCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/getCertificateCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.CertificateCredential.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteSSHCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/deleteSSHCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deletePWDCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/deletePWDCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteCertificateCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.service.ResourceSecretService/deleteCertificateCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/SharingService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/SharingService_pb2.py
new file mode 100644
index 0000000..0b5327c
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/SharingService_pb2.py
@@ -0,0 +1,1438 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: SharingService.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='SharingService.proto',
+  package='org.apache.custos.sharing.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x14SharingService.proto\x12!org.apache.custos.sharing.service\"c\n\nEntityType\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x12\n\ncreated_at\x18\x04 \x01(\x03\x12\x12\n\nupdated_at\x18\x05 \x01(\x03\"g\n\x0ePermissionType\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x12\n\ncreated_at\x18\x04 \x01(\x03\x12\x12\n\nupdated_at\x18\x05 \x01(\x03\"\xf0\x01\n\x06\x45ntity\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x10\n\x08owner_id\x18\x03 \x01(\t\x12\x11\n\tparent_id\x18\x04 \x01(\t\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12\x13\n\x0b\x62inary_data\x18\x07 \x01(\x0c\x12\x11\n\tfull_text\x18\x08 \x01(\t\x12\x1e\n\x16original_creation_time\x18\t \x01(\x03\x12\x12\n\ncreated_at\x18\n \x01(\x03\x12\x12\n\nupdated_at\x18\x0b \x01(\x03\x12\x14\n\x0cshared_count\x18\x0c \x01(\x05\"\x84\x01\n\rEntityRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12\x39\n\x06\x65ntity\x18\x03 \x01(\x0b\x32).org.apache.custos.sharing.service.Entity\x12\x12\n\nclient_sec\x18\x04 \x01(\t\"\x91\x01\n\x11\x45ntityTypeRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12\x42\n\x0b\x65ntity_type\x18\x03 \x01(\x0b\x32-.org.apache.custos.sharing.service.EntityType\x12\x12\n\nclient_sec\x18\x04 \x01(\t\"\x9d\x01\n\x15PermissionTypeRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12J\n\x0fpermission_type\x18\x03 \x01(\x0b\x32\x31.org.apache.custos.sharing.service.PermissionType\x12\x12\n\nclient_sec\x18\x04 \x01(\t\"\xb2\x01\n\x0eSearchCriteria\x12J\n\x0csearch_field\x18\x01 \x01(\x0e\x32\x34.org.apache.custos.sharing.service.EntitySearchField\x12\r\n\x05value\x18\x02 \x01(\t\x12\x45\n\tcondition\x18\x03 \x01(\x0e\x32\x32.org.apache.custos.sharing.service.SearchCondition\"\xdf\x01\n\rSearchRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12\x10\n\x08owner_id\x18\x03 \x01(\t\x12\x0e\n\x06offset\x18\x04 \x01(\x05\x12\r\n\x05limit\x18\x05 \x01(\x05\x12J\n\x0fsearch_criteria\x18\x06 \x03(\x0b\x32\x31.org.apache.custos.sharing.service.SearchCriteria\x12\x12\n\nclient_sec\x18\x07 \x01(\t\x12\x17\n\x0f\x61ssociating_ids\x18\x08 \x03(\t\"\xd4\x01\n\x11PermissionRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12\x39\n\x06\x65ntity\x18\x03 \x01(\x0b\x32).org.apache.custos.sharing.service.Entity\x12J\n\x0fpermission_type\x18\x04 \x01(\x0b\x32\x31.org.apache.custos.sharing.service.PermissionType\x12\x12\n\nclient_sec\x18\x05 \x01(\t\"\xf4\x01\n\x0eSharingRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12\x39\n\x06\x65ntity\x18\x03 \x01(\x0b\x32).org.apache.custos.sharing.service.Entity\x12J\n\x0fpermission_type\x18\x04 \x01(\x0b\x32\x31.org.apache.custos.sharing.service.PermissionType\x12\x10\n\x08owner_id\x18\x05 \x03(\t\x12\x0f\n\x07\x63\x61scade\x18\x06 \x01(\x08\x12\x12\n\nclient_sec\x18\x07 \x01(\t\"u\n\x16SharesFilteringRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12\x10\n\x08owner_id\x18\x05 \x03(\t\x12\x0f\n\x07\x63\x61scade\x18\x06 \x01(\x08\x12\x12\n\nclient_sec\x18\x07 \x01(\t\"\x18\n\x06Status\x12\x0e\n\x06status\x18\x01 \x01(\x08\"K\n\x0b\x45ntityTypes\x12<\n\x05types\x18\x01 \x03(\x0b\x32-.org.apache.custos.sharing.service.EntityType\"S\n\x0fPermissionTypes\x12@\n\x05types\x18\x01 \x03(\x0b\x32\x31.org.apache.custos.sharing.service.PermissionType\"K\n\x08\x45ntities\x12?\n\x0c\x65ntity_array\x18\x01 \x03(\x0b\x32).org.apache.custos.sharing.service.Entity\"!\n\x0cSharedOwners\x12\x11\n\towner_ids\x18\x01 \x03(\t*A\n\x0fSearchCondition\x12\t\n\x05\x45QUAL\x10\x00\x12\x08\n\x04LIKE\x10\x01\x12\x07\n\x03GTE\x10\x02\x12\x07\n\x03LTE\x10\x03\x12\x07\n\x03NOT\x10\x04*\xc6\x01\n\x11\x45ntitySearchField\x12\x08\n\x04NAME\x10\x00\x12\x0f\n\x0b\x44\x45SCRIPTION\x10\x01\x12\x06\n\x02ID\x10\x02\x12\r\n\tFULL_TEXT\x10\x03\x12\x0c\n\x08OWNER_ID\x10\x04\x12\x0e\n\nCREATED_AT\x10\x05\x12\x14\n\x10LAST_MODIFIED_AT\x10\x06\x12\x12\n\x0e\x45NTITY_TYPE_ID\x10\x07\x12\r\n\tPARENT_ID\x10\x08\x12\x10\n\x0cSHARED_COUNT\x10\t\x12\x16\n\x12PERMISSION_TYPE_ID\x10\n2\xbd\x17\n\x0eSharingService\x12s\n\x10\x63reateEntityType\x12\x34.org.apache.custos.sharing.service.EntityTypeRequest\x1a).org.apache.custos.sharing.service.Status\x12s\n\x10updateEntityType\x12\x34.org.apache.custos.sharing.service.EntityTypeRequest\x1a).org.apache.custos.sharing.service.Status\x12s\n\x10\x64\x65leteEntityType\x12\x34.org.apache.custos.sharing.service.EntityTypeRequest\x1a).org.apache.custos.sharing.service.Status\x12t\n\rgetEntityType\x12\x34.org.apache.custos.sharing.service.EntityTypeRequest\x1a-.org.apache.custos.sharing.service.EntityType\x12r\n\x0egetEntityTypes\x12\x30.org.apache.custos.sharing.service.SearchRequest\x1a..org.apache.custos.sharing.service.EntityTypes\x12{\n\x14\x63reatePermissionType\x12\x38.org.apache.custos.sharing.service.PermissionTypeRequest\x1a).org.apache.custos.sharing.service.Status\x12{\n\x14updatePermissionType\x12\x38.org.apache.custos.sharing.service.PermissionTypeRequest\x1a).org.apache.custos.sharing.service.Status\x12{\n\x14\x64\x65letePermissionType\x12\x38.org.apache.custos.sharing.service.PermissionTypeRequest\x1a).org.apache.custos.sharing.service.Status\x12\x80\x01\n\x11getPermissionType\x12\x38.org.apache.custos.sharing.service.PermissionTypeRequest\x1a\x31.org.apache.custos.sharing.service.PermissionType\x12z\n\x12getPermissionTypes\x12\x30.org.apache.custos.sharing.service.SearchRequest\x1a\x32.org.apache.custos.sharing.service.PermissionTypes\x12k\n\x0c\x63reateEntity\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Status\x12k\n\x0cupdateEntity\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Status\x12m\n\x0eisEntityExists\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Status\x12h\n\tgetEntity\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Entity\x12k\n\x0c\x64\x65leteEntity\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Status\x12o\n\x0esearchEntities\x12\x30.org.apache.custos.sharing.service.SearchRequest\x1a+.org.apache.custos.sharing.service.Entities\x12z\n\x14getListOfSharedUsers\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a/.org.apache.custos.sharing.service.SharedOwners\x12\x82\x01\n\x1cgetListOfDirectlySharedUsers\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a/.org.apache.custos.sharing.service.SharedOwners\x12{\n\x15getListOfSharedGroups\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a/.org.apache.custos.sharing.service.SharedOwners\x12\x83\x01\n\x1dgetListOfDirectlySharedGroups\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a/.org.apache.custos.sharing.service.SharedOwners\x12t\n\x14shareEntityWithUsers\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.Status\x12u\n\x15shareEntityWithGroups\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.Status\x12|\n\x1crevokeEntitySharingFromUsers\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.Status\x12}\n\x1drevokeEntitySharingFromGroups\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.Status\x12m\n\ruserHasAccess\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.StatusB\x02P\x01\x62\x06proto3'
+)
+
+_SEARCHCONDITION = _descriptor.EnumDescriptor(
+  name='SearchCondition',
+  full_name='org.apache.custos.sharing.service.SearchCondition',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='EQUAL', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='LIKE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='GTE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='LTE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='NOT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=2239,
+  serialized_end=2304,
+)
+_sym_db.RegisterEnumDescriptor(_SEARCHCONDITION)
+
+SearchCondition = enum_type_wrapper.EnumTypeWrapper(_SEARCHCONDITION)
+_ENTITYSEARCHFIELD = _descriptor.EnumDescriptor(
+  name='EntitySearchField',
+  full_name='org.apache.custos.sharing.service.EntitySearchField',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='NAME', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DESCRIPTION', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='ID', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='FULL_TEXT', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='OWNER_ID', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CREATED_AT', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='LAST_MODIFIED_AT', index=6, number=6,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='ENTITY_TYPE_ID', index=7, number=7,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='PARENT_ID', index=8, number=8,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SHARED_COUNT', index=9, number=9,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='PERMISSION_TYPE_ID', index=10, number=10,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=2307,
+  serialized_end=2505,
+)
+_sym_db.RegisterEnumDescriptor(_ENTITYSEARCHFIELD)
+
+EntitySearchField = enum_type_wrapper.EnumTypeWrapper(_ENTITYSEARCHFIELD)
+EQUAL = 0
+LIKE = 1
+GTE = 2
+LTE = 3
+NOT = 4
+NAME = 0
+DESCRIPTION = 1
+ID = 2
+FULL_TEXT = 3
+OWNER_ID = 4
+CREATED_AT = 5
+LAST_MODIFIED_AT = 6
+ENTITY_TYPE_ID = 7
+PARENT_ID = 8
+SHARED_COUNT = 9
+PERMISSION_TYPE_ID = 10
+
+
+
+_ENTITYTYPE = _descriptor.Descriptor(
+  name='EntityType',
+  full_name='org.apache.custos.sharing.service.EntityType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.sharing.service.EntityType.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.sharing.service.EntityType.name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='org.apache.custos.sharing.service.EntityType.description', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='created_at', full_name='org.apache.custos.sharing.service.EntityType.created_at', index=3,
+      number=4, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='updated_at', full_name='org.apache.custos.sharing.service.EntityType.updated_at', index=4,
+      number=5, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=59,
+  serialized_end=158,
+)
+
+
+_PERMISSIONTYPE = _descriptor.Descriptor(
+  name='PermissionType',
+  full_name='org.apache.custos.sharing.service.PermissionType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.sharing.service.PermissionType.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.sharing.service.PermissionType.name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='org.apache.custos.sharing.service.PermissionType.description', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='created_at', full_name='org.apache.custos.sharing.service.PermissionType.created_at', index=3,
+      number=4, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='updated_at', full_name='org.apache.custos.sharing.service.PermissionType.updated_at', index=4,
+      number=5, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=160,
+  serialized_end=263,
+)
+
+
+_ENTITY = _descriptor.Descriptor(
+  name='Entity',
+  full_name='org.apache.custos.sharing.service.Entity',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.sharing.service.Entity.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.sharing.service.Entity.type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='owner_id', full_name='org.apache.custos.sharing.service.Entity.owner_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='parent_id', full_name='org.apache.custos.sharing.service.Entity.parent_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.sharing.service.Entity.name', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='org.apache.custos.sharing.service.Entity.description', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='binary_data', full_name='org.apache.custos.sharing.service.Entity.binary_data', index=6,
+      number=7, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"",
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='full_text', full_name='org.apache.custos.sharing.service.Entity.full_text', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='original_creation_time', full_name='org.apache.custos.sharing.service.Entity.original_creation_time', index=8,
+      number=9, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='created_at', full_name='org.apache.custos.sharing.service.Entity.created_at', index=9,
+      number=10, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='updated_at', full_name='org.apache.custos.sharing.service.Entity.updated_at', index=10,
+      number=11, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='shared_count', full_name='org.apache.custos.sharing.service.Entity.shared_count', index=11,
+      number=12, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=266,
+  serialized_end=506,
+)
+
+
+_ENTITYREQUEST = _descriptor.Descriptor(
+  name='EntityRequest',
+  full_name='org.apache.custos.sharing.service.EntityRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.sharing.service.EntityRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.sharing.service.EntityRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='entity', full_name='org.apache.custos.sharing.service.EntityRequest.entity', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.sharing.service.EntityRequest.client_sec', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=509,
+  serialized_end=641,
+)
+
+
+_ENTITYTYPEREQUEST = _descriptor.Descriptor(
+  name='EntityTypeRequest',
+  full_name='org.apache.custos.sharing.service.EntityTypeRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.sharing.service.EntityTypeRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.sharing.service.EntityTypeRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='entity_type', full_name='org.apache.custos.sharing.service.EntityTypeRequest.entity_type', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.sharing.service.EntityTypeRequest.client_sec', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=644,
+  serialized_end=789,
+)
+
+
+_PERMISSIONTYPEREQUEST = _descriptor.Descriptor(
+  name='PermissionTypeRequest',
+  full_name='org.apache.custos.sharing.service.PermissionTypeRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.sharing.service.PermissionTypeRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.sharing.service.PermissionTypeRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='permission_type', full_name='org.apache.custos.sharing.service.PermissionTypeRequest.permission_type', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.sharing.service.PermissionTypeRequest.client_sec', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=792,
+  serialized_end=949,
+)
+
+
+_SEARCHCRITERIA = _descriptor.Descriptor(
+  name='SearchCriteria',
+  full_name='org.apache.custos.sharing.service.SearchCriteria',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='search_field', full_name='org.apache.custos.sharing.service.SearchCriteria.search_field', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.sharing.service.SearchCriteria.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='condition', full_name='org.apache.custos.sharing.service.SearchCriteria.condition', index=2,
+      number=3, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=952,
+  serialized_end=1130,
+)
+
+
+_SEARCHREQUEST = _descriptor.Descriptor(
+  name='SearchRequest',
+  full_name='org.apache.custos.sharing.service.SearchRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.sharing.service.SearchRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.sharing.service.SearchRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='owner_id', full_name='org.apache.custos.sharing.service.SearchRequest.owner_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='offset', full_name='org.apache.custos.sharing.service.SearchRequest.offset', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='limit', full_name='org.apache.custos.sharing.service.SearchRequest.limit', index=4,
+      number=5, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='search_criteria', full_name='org.apache.custos.sharing.service.SearchRequest.search_criteria', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.sharing.service.SearchRequest.client_sec', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='associating_ids', full_name='org.apache.custos.sharing.service.SearchRequest.associating_ids', index=7,
+      number=8, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1133,
+  serialized_end=1356,
+)
+
+
+_PERMISSIONREQUEST = _descriptor.Descriptor(
+  name='PermissionRequest',
+  full_name='org.apache.custos.sharing.service.PermissionRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.sharing.service.PermissionRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.sharing.service.PermissionRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='entity', full_name='org.apache.custos.sharing.service.PermissionRequest.entity', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='permission_type', full_name='org.apache.custos.sharing.service.PermissionRequest.permission_type', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.sharing.service.PermissionRequest.client_sec', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1359,
+  serialized_end=1571,
+)
+
+
+_SHARINGREQUEST = _descriptor.Descriptor(
+  name='SharingRequest',
+  full_name='org.apache.custos.sharing.service.SharingRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.sharing.service.SharingRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.sharing.service.SharingRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='entity', full_name='org.apache.custos.sharing.service.SharingRequest.entity', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='permission_type', full_name='org.apache.custos.sharing.service.SharingRequest.permission_type', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='owner_id', full_name='org.apache.custos.sharing.service.SharingRequest.owner_id', index=4,
+      number=5, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='cascade', full_name='org.apache.custos.sharing.service.SharingRequest.cascade', index=5,
+      number=6, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.sharing.service.SharingRequest.client_sec', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1574,
+  serialized_end=1818,
+)
+
+
+_SHARESFILTERINGREQUEST = _descriptor.Descriptor(
+  name='SharesFilteringRequest',
+  full_name='org.apache.custos.sharing.service.SharesFilteringRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.sharing.service.SharesFilteringRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.sharing.service.SharesFilteringRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='owner_id', full_name='org.apache.custos.sharing.service.SharesFilteringRequest.owner_id', index=2,
+      number=5, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='cascade', full_name='org.apache.custos.sharing.service.SharesFilteringRequest.cascade', index=3,
+      number=6, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.sharing.service.SharesFilteringRequest.client_sec', index=4,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1820,
+  serialized_end=1937,
+)
+
+
+_STATUS = _descriptor.Descriptor(
+  name='Status',
+  full_name='org.apache.custos.sharing.service.Status',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.sharing.service.Status.status', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1939,
+  serialized_end=1963,
+)
+
+
+_ENTITYTYPES = _descriptor.Descriptor(
+  name='EntityTypes',
+  full_name='org.apache.custos.sharing.service.EntityTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='types', full_name='org.apache.custos.sharing.service.EntityTypes.types', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1965,
+  serialized_end=2040,
+)
+
+
+_PERMISSIONTYPES = _descriptor.Descriptor(
+  name='PermissionTypes',
+  full_name='org.apache.custos.sharing.service.PermissionTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='types', full_name='org.apache.custos.sharing.service.PermissionTypes.types', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2042,
+  serialized_end=2125,
+)
+
+
+_ENTITIES = _descriptor.Descriptor(
+  name='Entities',
+  full_name='org.apache.custos.sharing.service.Entities',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='entity_array', full_name='org.apache.custos.sharing.service.Entities.entity_array', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2127,
+  serialized_end=2202,
+)
+
+
+_SHAREDOWNERS = _descriptor.Descriptor(
+  name='SharedOwners',
+  full_name='org.apache.custos.sharing.service.SharedOwners',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='owner_ids', full_name='org.apache.custos.sharing.service.SharedOwners.owner_ids', index=0,
+      number=1, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2204,
+  serialized_end=2237,
+)
+
+_ENTITYREQUEST.fields_by_name['entity'].message_type = _ENTITY
+_ENTITYTYPEREQUEST.fields_by_name['entity_type'].message_type = _ENTITYTYPE
+_PERMISSIONTYPEREQUEST.fields_by_name['permission_type'].message_type = _PERMISSIONTYPE
+_SEARCHCRITERIA.fields_by_name['search_field'].enum_type = _ENTITYSEARCHFIELD
+_SEARCHCRITERIA.fields_by_name['condition'].enum_type = _SEARCHCONDITION
+_SEARCHREQUEST.fields_by_name['search_criteria'].message_type = _SEARCHCRITERIA
+_PERMISSIONREQUEST.fields_by_name['entity'].message_type = _ENTITY
+_PERMISSIONREQUEST.fields_by_name['permission_type'].message_type = _PERMISSIONTYPE
+_SHARINGREQUEST.fields_by_name['entity'].message_type = _ENTITY
+_SHARINGREQUEST.fields_by_name['permission_type'].message_type = _PERMISSIONTYPE
+_ENTITYTYPES.fields_by_name['types'].message_type = _ENTITYTYPE
+_PERMISSIONTYPES.fields_by_name['types'].message_type = _PERMISSIONTYPE
+_ENTITIES.fields_by_name['entity_array'].message_type = _ENTITY
+DESCRIPTOR.message_types_by_name['EntityType'] = _ENTITYTYPE
+DESCRIPTOR.message_types_by_name['PermissionType'] = _PERMISSIONTYPE
+DESCRIPTOR.message_types_by_name['Entity'] = _ENTITY
+DESCRIPTOR.message_types_by_name['EntityRequest'] = _ENTITYREQUEST
+DESCRIPTOR.message_types_by_name['EntityTypeRequest'] = _ENTITYTYPEREQUEST
+DESCRIPTOR.message_types_by_name['PermissionTypeRequest'] = _PERMISSIONTYPEREQUEST
+DESCRIPTOR.message_types_by_name['SearchCriteria'] = _SEARCHCRITERIA
+DESCRIPTOR.message_types_by_name['SearchRequest'] = _SEARCHREQUEST
+DESCRIPTOR.message_types_by_name['PermissionRequest'] = _PERMISSIONREQUEST
+DESCRIPTOR.message_types_by_name['SharingRequest'] = _SHARINGREQUEST
+DESCRIPTOR.message_types_by_name['SharesFilteringRequest'] = _SHARESFILTERINGREQUEST
+DESCRIPTOR.message_types_by_name['Status'] = _STATUS
+DESCRIPTOR.message_types_by_name['EntityTypes'] = _ENTITYTYPES
+DESCRIPTOR.message_types_by_name['PermissionTypes'] = _PERMISSIONTYPES
+DESCRIPTOR.message_types_by_name['Entities'] = _ENTITIES
+DESCRIPTOR.message_types_by_name['SharedOwners'] = _SHAREDOWNERS
+DESCRIPTOR.enum_types_by_name['SearchCondition'] = _SEARCHCONDITION
+DESCRIPTOR.enum_types_by_name['EntitySearchField'] = _ENTITYSEARCHFIELD
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+EntityType = _reflection.GeneratedProtocolMessageType('EntityType', (_message.Message,), {
+  'DESCRIPTOR' : _ENTITYTYPE,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.EntityType)
+  })
+_sym_db.RegisterMessage(EntityType)
+
+PermissionType = _reflection.GeneratedProtocolMessageType('PermissionType', (_message.Message,), {
+  'DESCRIPTOR' : _PERMISSIONTYPE,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.PermissionType)
+  })
+_sym_db.RegisterMessage(PermissionType)
+
+Entity = _reflection.GeneratedProtocolMessageType('Entity', (_message.Message,), {
+  'DESCRIPTOR' : _ENTITY,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.Entity)
+  })
+_sym_db.RegisterMessage(Entity)
+
+EntityRequest = _reflection.GeneratedProtocolMessageType('EntityRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ENTITYREQUEST,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.EntityRequest)
+  })
+_sym_db.RegisterMessage(EntityRequest)
+
+EntityTypeRequest = _reflection.GeneratedProtocolMessageType('EntityTypeRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ENTITYTYPEREQUEST,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.EntityTypeRequest)
+  })
+_sym_db.RegisterMessage(EntityTypeRequest)
+
+PermissionTypeRequest = _reflection.GeneratedProtocolMessageType('PermissionTypeRequest', (_message.Message,), {
+  'DESCRIPTOR' : _PERMISSIONTYPEREQUEST,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.PermissionTypeRequest)
+  })
+_sym_db.RegisterMessage(PermissionTypeRequest)
+
+SearchCriteria = _reflection.GeneratedProtocolMessageType('SearchCriteria', (_message.Message,), {
+  'DESCRIPTOR' : _SEARCHCRITERIA,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.SearchCriteria)
+  })
+_sym_db.RegisterMessage(SearchCriteria)
+
+SearchRequest = _reflection.GeneratedProtocolMessageType('SearchRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SEARCHREQUEST,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.SearchRequest)
+  })
+_sym_db.RegisterMessage(SearchRequest)
+
+PermissionRequest = _reflection.GeneratedProtocolMessageType('PermissionRequest', (_message.Message,), {
+  'DESCRIPTOR' : _PERMISSIONREQUEST,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.PermissionRequest)
+  })
+_sym_db.RegisterMessage(PermissionRequest)
+
+SharingRequest = _reflection.GeneratedProtocolMessageType('SharingRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SHARINGREQUEST,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.SharingRequest)
+  })
+_sym_db.RegisterMessage(SharingRequest)
+
+SharesFilteringRequest = _reflection.GeneratedProtocolMessageType('SharesFilteringRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SHARESFILTERINGREQUEST,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.SharesFilteringRequest)
+  })
+_sym_db.RegisterMessage(SharesFilteringRequest)
+
+Status = _reflection.GeneratedProtocolMessageType('Status', (_message.Message,), {
+  'DESCRIPTOR' : _STATUS,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.Status)
+  })
+_sym_db.RegisterMessage(Status)
+
+EntityTypes = _reflection.GeneratedProtocolMessageType('EntityTypes', (_message.Message,), {
+  'DESCRIPTOR' : _ENTITYTYPES,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.EntityTypes)
+  })
+_sym_db.RegisterMessage(EntityTypes)
+
+PermissionTypes = _reflection.GeneratedProtocolMessageType('PermissionTypes', (_message.Message,), {
+  'DESCRIPTOR' : _PERMISSIONTYPES,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.PermissionTypes)
+  })
+_sym_db.RegisterMessage(PermissionTypes)
+
+Entities = _reflection.GeneratedProtocolMessageType('Entities', (_message.Message,), {
+  'DESCRIPTOR' : _ENTITIES,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.Entities)
+  })
+_sym_db.RegisterMessage(Entities)
+
+SharedOwners = _reflection.GeneratedProtocolMessageType('SharedOwners', (_message.Message,), {
+  'DESCRIPTOR' : _SHAREDOWNERS,
+  '__module__' : 'SharingService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.sharing.service.SharedOwners)
+  })
+_sym_db.RegisterMessage(SharedOwners)
+
+
+DESCRIPTOR._options = None
+
+_SHARINGSERVICE = _descriptor.ServiceDescriptor(
+  name='SharingService',
+  full_name='org.apache.custos.sharing.service.SharingService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=2508,
+  serialized_end=5513,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='createEntityType',
+    full_name='org.apache.custos.sharing.service.SharingService.createEntityType',
+    index=0,
+    containing_service=None,
+    input_type=_ENTITYTYPEREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateEntityType',
+    full_name='org.apache.custos.sharing.service.SharingService.updateEntityType',
+    index=1,
+    containing_service=None,
+    input_type=_ENTITYTYPEREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteEntityType',
+    full_name='org.apache.custos.sharing.service.SharingService.deleteEntityType',
+    index=2,
+    containing_service=None,
+    input_type=_ENTITYTYPEREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getEntityType',
+    full_name='org.apache.custos.sharing.service.SharingService.getEntityType',
+    index=3,
+    containing_service=None,
+    input_type=_ENTITYTYPEREQUEST,
+    output_type=_ENTITYTYPE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getEntityTypes',
+    full_name='org.apache.custos.sharing.service.SharingService.getEntityTypes',
+    index=4,
+    containing_service=None,
+    input_type=_SEARCHREQUEST,
+    output_type=_ENTITYTYPES,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createPermissionType',
+    full_name='org.apache.custos.sharing.service.SharingService.createPermissionType',
+    index=5,
+    containing_service=None,
+    input_type=_PERMISSIONTYPEREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updatePermissionType',
+    full_name='org.apache.custos.sharing.service.SharingService.updatePermissionType',
+    index=6,
+    containing_service=None,
+    input_type=_PERMISSIONTYPEREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deletePermissionType',
+    full_name='org.apache.custos.sharing.service.SharingService.deletePermissionType',
+    index=7,
+    containing_service=None,
+    input_type=_PERMISSIONTYPEREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getPermissionType',
+    full_name='org.apache.custos.sharing.service.SharingService.getPermissionType',
+    index=8,
+    containing_service=None,
+    input_type=_PERMISSIONTYPEREQUEST,
+    output_type=_PERMISSIONTYPE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getPermissionTypes',
+    full_name='org.apache.custos.sharing.service.SharingService.getPermissionTypes',
+    index=9,
+    containing_service=None,
+    input_type=_SEARCHREQUEST,
+    output_type=_PERMISSIONTYPES,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createEntity',
+    full_name='org.apache.custos.sharing.service.SharingService.createEntity',
+    index=10,
+    containing_service=None,
+    input_type=_ENTITYREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateEntity',
+    full_name='org.apache.custos.sharing.service.SharingService.updateEntity',
+    index=11,
+    containing_service=None,
+    input_type=_ENTITYREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isEntityExists',
+    full_name='org.apache.custos.sharing.service.SharingService.isEntityExists',
+    index=12,
+    containing_service=None,
+    input_type=_ENTITYREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getEntity',
+    full_name='org.apache.custos.sharing.service.SharingService.getEntity',
+    index=13,
+    containing_service=None,
+    input_type=_ENTITYREQUEST,
+    output_type=_ENTITY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteEntity',
+    full_name='org.apache.custos.sharing.service.SharingService.deleteEntity',
+    index=14,
+    containing_service=None,
+    input_type=_ENTITYREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='searchEntities',
+    full_name='org.apache.custos.sharing.service.SharingService.searchEntities',
+    index=15,
+    containing_service=None,
+    input_type=_SEARCHREQUEST,
+    output_type=_ENTITIES,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getListOfSharedUsers',
+    full_name='org.apache.custos.sharing.service.SharingService.getListOfSharedUsers',
+    index=16,
+    containing_service=None,
+    input_type=_SHARINGREQUEST,
+    output_type=_SHAREDOWNERS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getListOfDirectlySharedUsers',
+    full_name='org.apache.custos.sharing.service.SharingService.getListOfDirectlySharedUsers',
+    index=17,
+    containing_service=None,
+    input_type=_SHARINGREQUEST,
+    output_type=_SHAREDOWNERS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getListOfSharedGroups',
+    full_name='org.apache.custos.sharing.service.SharingService.getListOfSharedGroups',
+    index=18,
+    containing_service=None,
+    input_type=_SHARINGREQUEST,
+    output_type=_SHAREDOWNERS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getListOfDirectlySharedGroups',
+    full_name='org.apache.custos.sharing.service.SharingService.getListOfDirectlySharedGroups',
+    index=19,
+    containing_service=None,
+    input_type=_SHARINGREQUEST,
+    output_type=_SHAREDOWNERS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='shareEntityWithUsers',
+    full_name='org.apache.custos.sharing.service.SharingService.shareEntityWithUsers',
+    index=20,
+    containing_service=None,
+    input_type=_SHARINGREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='shareEntityWithGroups',
+    full_name='org.apache.custos.sharing.service.SharingService.shareEntityWithGroups',
+    index=21,
+    containing_service=None,
+    input_type=_SHARINGREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='revokeEntitySharingFromUsers',
+    full_name='org.apache.custos.sharing.service.SharingService.revokeEntitySharingFromUsers',
+    index=22,
+    containing_service=None,
+    input_type=_SHARINGREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='revokeEntitySharingFromGroups',
+    full_name='org.apache.custos.sharing.service.SharingService.revokeEntitySharingFromGroups',
+    index=23,
+    containing_service=None,
+    input_type=_SHARINGREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='userHasAccess',
+    full_name='org.apache.custos.sharing.service.SharingService.userHasAccess',
+    index=24,
+    containing_service=None,
+    input_type=_SHARINGREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_SHARINGSERVICE)
+
+DESCRIPTOR.services_by_name['SharingService'] = _SHARINGSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/SharingService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/SharingService_pb2_grpc.py
new file mode 100644
index 0000000..ff2f596
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/SharingService_pb2_grpc.py
@@ -0,0 +1,858 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import SharingService_pb2 as SharingService__pb2
+
+
+class SharingServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.createEntityType = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/createEntityType',
+                request_serializer=SharingService__pb2.EntityTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.updateEntityType = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/updateEntityType',
+                request_serializer=SharingService__pb2.EntityTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.deleteEntityType = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/deleteEntityType',
+                request_serializer=SharingService__pb2.EntityTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.getEntityType = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/getEntityType',
+                request_serializer=SharingService__pb2.EntityTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.EntityType.FromString,
+                )
+        self.getEntityTypes = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/getEntityTypes',
+                request_serializer=SharingService__pb2.SearchRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.EntityTypes.FromString,
+                )
+        self.createPermissionType = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/createPermissionType',
+                request_serializer=SharingService__pb2.PermissionTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.updatePermissionType = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/updatePermissionType',
+                request_serializer=SharingService__pb2.PermissionTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.deletePermissionType = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/deletePermissionType',
+                request_serializer=SharingService__pb2.PermissionTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.getPermissionType = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/getPermissionType',
+                request_serializer=SharingService__pb2.PermissionTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.PermissionType.FromString,
+                )
+        self.getPermissionTypes = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/getPermissionTypes',
+                request_serializer=SharingService__pb2.SearchRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.PermissionTypes.FromString,
+                )
+        self.createEntity = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/createEntity',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.updateEntity = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/updateEntity',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.isEntityExists = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/isEntityExists',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.getEntity = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/getEntity',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Entity.FromString,
+                )
+        self.deleteEntity = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/deleteEntity',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.searchEntities = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/searchEntities',
+                request_serializer=SharingService__pb2.SearchRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Entities.FromString,
+                )
+        self.getListOfSharedUsers = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/getListOfSharedUsers',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.SharedOwners.FromString,
+                )
+        self.getListOfDirectlySharedUsers = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/getListOfDirectlySharedUsers',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.SharedOwners.FromString,
+                )
+        self.getListOfSharedGroups = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/getListOfSharedGroups',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.SharedOwners.FromString,
+                )
+        self.getListOfDirectlySharedGroups = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/getListOfDirectlySharedGroups',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.SharedOwners.FromString,
+                )
+        self.shareEntityWithUsers = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/shareEntityWithUsers',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.shareEntityWithGroups = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/shareEntityWithGroups',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.revokeEntitySharingFromUsers = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/revokeEntitySharingFromUsers',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.revokeEntitySharingFromGroups = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/revokeEntitySharingFromGroups',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.userHasAccess = channel.unary_unary(
+                '/org.apache.custos.sharing.service.SharingService/userHasAccess',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+
+
+class SharingServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def createEntityType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateEntityType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteEntityType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getEntityType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getEntityTypes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def createPermissionType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updatePermissionType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deletePermissionType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getPermissionType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getPermissionTypes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def createEntity(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateEntity(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isEntityExists(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getEntity(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteEntity(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def searchEntities(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getListOfSharedUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getListOfDirectlySharedUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getListOfSharedGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getListOfDirectlySharedGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def shareEntityWithUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def shareEntityWithGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def revokeEntitySharingFromUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def revokeEntitySharingFromGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def userHasAccess(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_SharingServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'createEntityType': grpc.unary_unary_rpc_method_handler(
+                    servicer.createEntityType,
+                    request_deserializer=SharingService__pb2.EntityTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'updateEntityType': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateEntityType,
+                    request_deserializer=SharingService__pb2.EntityTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'deleteEntityType': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteEntityType,
+                    request_deserializer=SharingService__pb2.EntityTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'getEntityType': grpc.unary_unary_rpc_method_handler(
+                    servicer.getEntityType,
+                    request_deserializer=SharingService__pb2.EntityTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.EntityType.SerializeToString,
+            ),
+            'getEntityTypes': grpc.unary_unary_rpc_method_handler(
+                    servicer.getEntityTypes,
+                    request_deserializer=SharingService__pb2.SearchRequest.FromString,
+                    response_serializer=SharingService__pb2.EntityTypes.SerializeToString,
+            ),
+            'createPermissionType': grpc.unary_unary_rpc_method_handler(
+                    servicer.createPermissionType,
+                    request_deserializer=SharingService__pb2.PermissionTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'updatePermissionType': grpc.unary_unary_rpc_method_handler(
+                    servicer.updatePermissionType,
+                    request_deserializer=SharingService__pb2.PermissionTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'deletePermissionType': grpc.unary_unary_rpc_method_handler(
+                    servicer.deletePermissionType,
+                    request_deserializer=SharingService__pb2.PermissionTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'getPermissionType': grpc.unary_unary_rpc_method_handler(
+                    servicer.getPermissionType,
+                    request_deserializer=SharingService__pb2.PermissionTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.PermissionType.SerializeToString,
+            ),
+            'getPermissionTypes': grpc.unary_unary_rpc_method_handler(
+                    servicer.getPermissionTypes,
+                    request_deserializer=SharingService__pb2.SearchRequest.FromString,
+                    response_serializer=SharingService__pb2.PermissionTypes.SerializeToString,
+            ),
+            'createEntity': grpc.unary_unary_rpc_method_handler(
+                    servicer.createEntity,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'updateEntity': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateEntity,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'isEntityExists': grpc.unary_unary_rpc_method_handler(
+                    servicer.isEntityExists,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'getEntity': grpc.unary_unary_rpc_method_handler(
+                    servicer.getEntity,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Entity.SerializeToString,
+            ),
+            'deleteEntity': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteEntity,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'searchEntities': grpc.unary_unary_rpc_method_handler(
+                    servicer.searchEntities,
+                    request_deserializer=SharingService__pb2.SearchRequest.FromString,
+                    response_serializer=SharingService__pb2.Entities.SerializeToString,
+            ),
+            'getListOfSharedUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.getListOfSharedUsers,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.SharedOwners.SerializeToString,
+            ),
+            'getListOfDirectlySharedUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.getListOfDirectlySharedUsers,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.SharedOwners.SerializeToString,
+            ),
+            'getListOfSharedGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getListOfSharedGroups,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.SharedOwners.SerializeToString,
+            ),
+            'getListOfDirectlySharedGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getListOfDirectlySharedGroups,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.SharedOwners.SerializeToString,
+            ),
+            'shareEntityWithUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.shareEntityWithUsers,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'shareEntityWithGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.shareEntityWithGroups,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'revokeEntitySharingFromUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.revokeEntitySharingFromUsers,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'revokeEntitySharingFromGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.revokeEntitySharingFromGroups,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'userHasAccess': grpc.unary_unary_rpc_method_handler(
+                    servicer.userHasAccess,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'org.apache.custos.sharing.service.SharingService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class SharingService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def createEntityType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/createEntityType',
+            SharingService__pb2.EntityTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateEntityType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/updateEntityType',
+            SharingService__pb2.EntityTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteEntityType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/deleteEntityType',
+            SharingService__pb2.EntityTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getEntityType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/getEntityType',
+            SharingService__pb2.EntityTypeRequest.SerializeToString,
+            SharingService__pb2.EntityType.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getEntityTypes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/getEntityTypes',
+            SharingService__pb2.SearchRequest.SerializeToString,
+            SharingService__pb2.EntityTypes.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def createPermissionType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/createPermissionType',
+            SharingService__pb2.PermissionTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updatePermissionType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/updatePermissionType',
+            SharingService__pb2.PermissionTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deletePermissionType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/deletePermissionType',
+            SharingService__pb2.PermissionTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getPermissionType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/getPermissionType',
+            SharingService__pb2.PermissionTypeRequest.SerializeToString,
+            SharingService__pb2.PermissionType.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getPermissionTypes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/getPermissionTypes',
+            SharingService__pb2.SearchRequest.SerializeToString,
+            SharingService__pb2.PermissionTypes.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def createEntity(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/createEntity',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateEntity(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/updateEntity',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isEntityExists(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/isEntityExists',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getEntity(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/getEntity',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Entity.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteEntity(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/deleteEntity',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def searchEntities(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/searchEntities',
+            SharingService__pb2.SearchRequest.SerializeToString,
+            SharingService__pb2.Entities.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getListOfSharedUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/getListOfSharedUsers',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.SharedOwners.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getListOfDirectlySharedUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/getListOfDirectlySharedUsers',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.SharedOwners.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getListOfSharedGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/getListOfSharedGroups',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.SharedOwners.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getListOfDirectlySharedGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/getListOfDirectlySharedGroups',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.SharedOwners.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def shareEntityWithUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/shareEntityWithUsers',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def shareEntityWithGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/shareEntityWithGroups',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def revokeEntitySharingFromUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/revokeEntitySharingFromUsers',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def revokeEntitySharingFromGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/revokeEntitySharingFromGroups',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def userHasAccess(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.service.SharingService/userHasAccess',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/TenantProfileService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/TenantProfileService_pb2.py
new file mode 100644
index 0000000..f26ecb6
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/TenantProfileService_pb2.py
@@ -0,0 +1,1228 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: TenantProfileService.proto
+
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='TenantProfileService.proto',
+  package='org.apache.custos.tenant.profile.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n\x1aTenantProfileService.proto\x12(org.apache.custos.tenant.profile.service\"\x9b\x06\n\x06Tenant\x12\x11\n\ttenant_id\x18\x01 \x01(\x03\x12\x13\n\x0b\x63lient_name\x18\x02 \x01(\t\x12\x17\n\x0frequester_email\x18\x04 \x01(\t\x12\x18\n\x10\x61\x64min_first_name\x18\x05 \x01(\t\x12\x17\n\x0f\x61\x64min_last_name\x18\x06 \x01(\t\x12\x13\n\x0b\x61\x64min_email\x18\x07 \x01(\t\x12\x16\n\x0e\x61\x64min_username\x18\x08 \x01(\t\x12\x16\n\x0e\x61\x64min_password\x18\t \x01(\t\x12M\n\rtenant_status\x18\n \x01(\x0e\x32\x36.org.apache.custos.tenant.profile.service.TenantStatus\x12\x10\n\x08\x63ontacts\x18\x0b \x03(\t\x12\x15\n\rredirect_uris\x18\x0c \x03(\t\x12\x12\n\nclient_uri\x18\r \x01(\t\x12\r\n\x05scope\x18\x0e \x01(\t\x12\x0e\n\x06\x64omain\x18\x0f \x01(\t\x12\x0f\n\x07\x63omment\x18\x10 \x01(\t\x12\x10\n\x08logo_uri\x18\x11 \x01(\t\x12\x18\n\x10parent_tenant_id\x18\x12 \x01(\x03\x12\x18\n\x10\x61pplication_type\x18\x13 \x01(\t\x12\"\n\x1atoken_endpoint_auth_method\x18\x14 \x01(\t\x12\x10\n\x08jwks_uri\x18\x15 \x01(\t\x12#\n\x1b\x65xample_extension_parameter\x18\x16 \x01(\t\x12\x0f\n\x07tos_uri\x18\x17 \x01(\t\x12\x12\n\npolicy_uri\x18\x18 \x01(\t\x12H\n\x04jwks\x18\x19 \x03(\x0b\x32:.org.apache.custos.tenant.profile.service.Tenant.JwksEntry\x12\x13\n\x0bsoftware_id\x18\x1a \x01(\t\x12\x18\n\x10software_version\x18\x1b \x01(\t\x12\x1d\n\x15refesh_token_lifetime\x18\x1c \x01(\x03\x12\x11\n\tclient_id\x18\x1d \x01(\t\x1a+\n\tJwksEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"~\n\x1dTenantAttributeUpdateMetadata\x12\x18\n\x10updatedAttribute\x18\x01 \x01(\t\x12\x1d\n\x15updatedAttributeValue\x18\x02 \x01(\t\x12\x11\n\tupdatedBy\x18\x03 \x01(\t\x12\x11\n\tupdatedAt\x18\x04 \x01(\t\"\x91\x01\n\x1aTenantStatusUpdateMetadata\x12M\n\rupdatedStatus\x18\x01 \x01(\x0e\x32\x36.org.apache.custos.tenant.profile.service.TenantStatus\x12\x11\n\tupdatedBy\x18\x02 \x01(\t\x12\x11\n\tupdatedAt\x18\x03 \x01(\t\"%\n\x11\x41\x64\x64TenantResponse\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\"X\n\x14UpdateTenantResponse\x12@\n\x06tenant\x18\x01 \x01(\x0b\x32\x30.org.apache.custos.tenant.profile.service.Tenant\"$\n\x10GetTenantRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\"U\n\x11GetTenantResponse\x12@\n\x06tenant\x18\x01 \x01(\x0b\x32\x30.org.apache.custos.tenant.profile.service.Tenant\"Y\n\x15GetAllTenantsResponse\x12@\n\x06tenant\x18\x01 \x03(\x0b\x32\x30.org.apache.custos.tenant.profile.service.Tenant\"(\n\x14IsTenantExistRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\"(\n\x15IsTenantExistResponse\x12\x0f\n\x07isExist\x18\x01 \x01(\x08\"5\n\x1bGetAllTenantsForUserRequest\x12\x16\n\x0erequesterEmail\x18\x01 \x01(\t\"`\n\x1cGetAllTenantsForUserResponse\x12@\n\x06tenant\x18\x01 \x03(\x0b\x32\x30.org.apache.custos.tenant.profile.service.Tenant\"\xc0\x01\n\x13UpdateStatusRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x46\n\x06status\x18\x02 \x01(\x0e\x32\x36.org.apache.custos.tenant.profile.service.TenantStatus\x12\x11\n\tupdatedBy\x18\x03 \x01(\t\x12\x10\n\x08tenantId\x18\x04 \x01(\x03\x12\x14\n\x0csuper_tenant\x18\x05 \x01(\x08\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x06 \x01(\t\"p\n\x14UpdateStatusResponse\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x46\n\x06status\x18\x02 \x01(\x0e\x32\x36.org.apache.custos.tenant.profile.service.TenantStatus\"(\n\x14GetAuditTrailRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\"{\n!GetStatusUpdateAuditTrailResponse\x12V\n\x08metadata\x18\x01 \x03(\x0b\x32\x44.org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata\"\x81\x01\n$GetAttributeUpdateAuditTrailResponse\x12Y\n\x08metadata\x18\x02 \x03(\x0b\x32G.org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata\"\xa6\x01\n\x11GetTenantsRequest\x12\x0e\n\x06offset\x18\x01 \x01(\x05\x12\r\n\x05limit\x18\x02 \x01(\x05\x12\x11\n\tparent_id\x18\x03 \x01(\x03\x12\x46\n\x06status\x18\x04 \x01(\x0e\x32\x36.org.apache.custos.tenant.profile.service.TenantStatus\x12\x17\n\x0frequester_email\x18\x05 \x01(\t*c\n\x0cTenantStatus\x12\r\n\tREQUESTED\x10\x00\x12\x0c\n\x08\x41PPROVED\x10\x01\x12\n\n\x06\x44\x45NIED\x10\x02\x12\r\n\tCANCELLED\x10\x03\x12\n\n\x06\x41\x43TIVE\x10\x04\x12\x0f\n\x0b\x44\x45\x41\x43TIVATED\x10\x05\x32\xcb\n\n\x14TenantProfileService\x12o\n\taddTenant\x12\x30.org.apache.custos.tenant.profile.service.Tenant\x1a\x30.org.apache.custos.tenant.profile.service.Tenant\x12r\n\x0cupdateTenant\x12\x30.org.apache.custos.tenant.profile.service.Tenant\x1a\x30.org.apache.custos.tenant.profile.service.Tenant\x12\x84\x01\n\tgetTenant\x12:.org.apache.custos.tenant.profile.service.GetTenantRequest\x1a;.org.apache.custos.tenant.profile.service.GetTenantResponse\x12\x93\x01\n\x12updateTenantStatus\x12=.org.apache.custos.tenant.profile.service.UpdateStatusRequest\x1a>.org.apache.custos.tenant.profile.service.UpdateStatusResponse\x12\x8d\x01\n\rgetAllTenants\x12;.org.apache.custos.tenant.profile.service.GetTenantsRequest\x1a?.org.apache.custos.tenant.profile.service.GetAllTenantsResponse\x12\x90\x01\n\risTenantExist\x12>.org.apache.custos.tenant.profile.service.IsTenantExistRequest\x1a?.org.apache.custos.tenant.profile.service.IsTenantExistResponse\x12\xa5\x01\n\x14getAllTenantsForUser\x12\x45.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest\x1a\x46.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse\x12\xae\x01\n\x1fgetTenantStatusUpdateAuditTrail\x12>.org.apache.custos.tenant.profile.service.GetAuditTrailRequest\x1aK.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse\x12\xb4\x01\n\"getTenantAttributeUpdateAuditTrail\x12>.org.apache.custos.tenant.profile.service.GetAuditTrailRequest\x1aN.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponseB\x02P\x01\x62\x06proto3'
+)
+
+_TENANTSTATUS = _descriptor.EnumDescriptor(
+  name='TenantStatus',
+  full_name='org.apache.custos.tenant.profile.service.TenantStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='REQUESTED', index=0, number=0,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='APPROVED', index=1, number=1,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='DENIED', index=2, number=2,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CANCELLED', index=3, number=3,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ACTIVE', index=4, number=4,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='DEACTIVATED', index=5, number=5,
+      serialized_options=None,
+      type=None),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=2505,
+  serialized_end=2604,
+)
+_sym_db.RegisterEnumDescriptor(_TENANTSTATUS)
+
+TenantStatus = enum_type_wrapper.EnumTypeWrapper(_TENANTSTATUS)
+REQUESTED = 0
+APPROVED = 1
+DENIED = 2
+CANCELLED = 3
+ACTIVE = 4
+DEACTIVATED = 5
+
+
+
+_TENANT_JWKSENTRY = _descriptor.Descriptor(
+  name='JwksEntry',
+  full_name='org.apache.custos.tenant.profile.service.Tenant.JwksEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.tenant.profile.service.Tenant.JwksEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.tenant.profile.service.Tenant.JwksEntry.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=b'8\001',
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=825,
+  serialized_end=868,
+)
+
+_TENANT = _descriptor.Descriptor(
+  name='Tenant',
+  full_name='org.apache.custos.tenant.profile.service.Tenant',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.tenant.profile.service.Tenant.tenant_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_name', full_name='org.apache.custos.tenant.profile.service.Tenant.client_name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='requester_email', full_name='org.apache.custos.tenant.profile.service.Tenant.requester_email', index=2,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='admin_first_name', full_name='org.apache.custos.tenant.profile.service.Tenant.admin_first_name', index=3,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='admin_last_name', full_name='org.apache.custos.tenant.profile.service.Tenant.admin_last_name', index=4,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='admin_email', full_name='org.apache.custos.tenant.profile.service.Tenant.admin_email', index=5,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='admin_username', full_name='org.apache.custos.tenant.profile.service.Tenant.admin_username', index=6,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='admin_password', full_name='org.apache.custos.tenant.profile.service.Tenant.admin_password', index=7,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenant_status', full_name='org.apache.custos.tenant.profile.service.Tenant.tenant_status', index=8,
+      number=10, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='contacts', full_name='org.apache.custos.tenant.profile.service.Tenant.contacts', index=9,
+      number=11, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='redirect_uris', full_name='org.apache.custos.tenant.profile.service.Tenant.redirect_uris', index=10,
+      number=12, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_uri', full_name='org.apache.custos.tenant.profile.service.Tenant.client_uri', index=11,
+      number=13, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.tenant.profile.service.Tenant.scope', index=12,
+      number=14, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='domain', full_name='org.apache.custos.tenant.profile.service.Tenant.domain', index=13,
+      number=15, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='comment', full_name='org.apache.custos.tenant.profile.service.Tenant.comment', index=14,
+      number=16, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='logo_uri', full_name='org.apache.custos.tenant.profile.service.Tenant.logo_uri', index=15,
+      number=17, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='parent_tenant_id', full_name='org.apache.custos.tenant.profile.service.Tenant.parent_tenant_id', index=16,
+      number=18, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='application_type', full_name='org.apache.custos.tenant.profile.service.Tenant.application_type', index=17,
+      number=19, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='token_endpoint_auth_method', full_name='org.apache.custos.tenant.profile.service.Tenant.token_endpoint_auth_method', index=18,
+      number=20, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='jwks_uri', full_name='org.apache.custos.tenant.profile.service.Tenant.jwks_uri', index=19,
+      number=21, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='example_extension_parameter', full_name='org.apache.custos.tenant.profile.service.Tenant.example_extension_parameter', index=20,
+      number=22, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tos_uri', full_name='org.apache.custos.tenant.profile.service.Tenant.tos_uri', index=21,
+      number=23, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='policy_uri', full_name='org.apache.custos.tenant.profile.service.Tenant.policy_uri', index=22,
+      number=24, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='jwks', full_name='org.apache.custos.tenant.profile.service.Tenant.jwks', index=23,
+      number=25, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='software_id', full_name='org.apache.custos.tenant.profile.service.Tenant.software_id', index=24,
+      number=26, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='software_version', full_name='org.apache.custos.tenant.profile.service.Tenant.software_version', index=25,
+      number=27, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='refesh_token_lifetime', full_name='org.apache.custos.tenant.profile.service.Tenant.refesh_token_lifetime', index=26,
+      number=28, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.tenant.profile.service.Tenant.client_id', index=27,
+      number=29, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TENANT_JWKSENTRY, ],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=73,
+  serialized_end=868,
+)
+
+
+_TENANTATTRIBUTEUPDATEMETADATA = _descriptor.Descriptor(
+  name='TenantAttributeUpdateMetadata',
+  full_name='org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='updatedAttribute', full_name='org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.updatedAttribute', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='updatedAttributeValue', full_name='org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.updatedAttributeValue', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='updatedBy', full_name='org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.updatedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='updatedAt', full_name='org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata.updatedAt', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=870,
+  serialized_end=996,
+)
+
+
+_TENANTSTATUSUPDATEMETADATA = _descriptor.Descriptor(
+  name='TenantStatusUpdateMetadata',
+  full_name='org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='updatedStatus', full_name='org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.updatedStatus', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='updatedBy', full_name='org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.updatedBy', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='updatedAt', full_name='org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata.updatedAt', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=999,
+  serialized_end=1144,
+)
+
+
+_ADDTENANTRESPONSE = _descriptor.Descriptor(
+  name='AddTenantResponse',
+  full_name='org.apache.custos.tenant.profile.service.AddTenantResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.tenant.profile.service.AddTenantResponse.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1146,
+  serialized_end=1183,
+)
+
+
+_UPDATETENANTRESPONSE = _descriptor.Descriptor(
+  name='UpdateTenantResponse',
+  full_name='org.apache.custos.tenant.profile.service.UpdateTenantResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant', full_name='org.apache.custos.tenant.profile.service.UpdateTenantResponse.tenant', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1185,
+  serialized_end=1273,
+)
+
+
+_GETTENANTREQUEST = _descriptor.Descriptor(
+  name='GetTenantRequest',
+  full_name='org.apache.custos.tenant.profile.service.GetTenantRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.tenant.profile.service.GetTenantRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1275,
+  serialized_end=1311,
+)
+
+
+_GETTENANTRESPONSE = _descriptor.Descriptor(
+  name='GetTenantResponse',
+  full_name='org.apache.custos.tenant.profile.service.GetTenantResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant', full_name='org.apache.custos.tenant.profile.service.GetTenantResponse.tenant', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1313,
+  serialized_end=1398,
+)
+
+
+_GETALLTENANTSRESPONSE = _descriptor.Descriptor(
+  name='GetAllTenantsResponse',
+  full_name='org.apache.custos.tenant.profile.service.GetAllTenantsResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant', full_name='org.apache.custos.tenant.profile.service.GetAllTenantsResponse.tenant', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1400,
+  serialized_end=1489,
+)
+
+
+_ISTENANTEXISTREQUEST = _descriptor.Descriptor(
+  name='IsTenantExistRequest',
+  full_name='org.apache.custos.tenant.profile.service.IsTenantExistRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.tenant.profile.service.IsTenantExistRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1491,
+  serialized_end=1531,
+)
+
+
+_ISTENANTEXISTRESPONSE = _descriptor.Descriptor(
+  name='IsTenantExistResponse',
+  full_name='org.apache.custos.tenant.profile.service.IsTenantExistResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='isExist', full_name='org.apache.custos.tenant.profile.service.IsTenantExistResponse.isExist', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1533,
+  serialized_end=1573,
+)
+
+
+_GETALLTENANTSFORUSERREQUEST = _descriptor.Descriptor(
+  name='GetAllTenantsForUserRequest',
+  full_name='org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='requesterEmail', full_name='org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest.requesterEmail', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1575,
+  serialized_end=1628,
+)
+
+
+_GETALLTENANTSFORUSERRESPONSE = _descriptor.Descriptor(
+  name='GetAllTenantsForUserResponse',
+  full_name='org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant', full_name='org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse.tenant', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1630,
+  serialized_end=1726,
+)
+
+
+_UPDATESTATUSREQUEST = _descriptor.Descriptor(
+  name='UpdateStatusRequest',
+  full_name='org.apache.custos.tenant.profile.service.UpdateStatusRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.tenant.profile.service.UpdateStatusRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.tenant.profile.service.UpdateStatusRequest.status', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='updatedBy', full_name='org.apache.custos.tenant.profile.service.UpdateStatusRequest.updatedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.tenant.profile.service.UpdateStatusRequest.tenantId', index=3,
+      number=4, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='super_tenant', full_name='org.apache.custos.tenant.profile.service.UpdateStatusRequest.super_tenant', index=4,
+      number=5, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.tenant.profile.service.UpdateStatusRequest.accessToken', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1729,
+  serialized_end=1921,
+)
+
+
+_UPDATESTATUSRESPONSE = _descriptor.Descriptor(
+  name='UpdateStatusResponse',
+  full_name='org.apache.custos.tenant.profile.service.UpdateStatusResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.tenant.profile.service.UpdateStatusResponse.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.tenant.profile.service.UpdateStatusResponse.status', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1923,
+  serialized_end=2035,
+)
+
+
+_GETAUDITTRAILREQUEST = _descriptor.Descriptor(
+  name='GetAuditTrailRequest',
+  full_name='org.apache.custos.tenant.profile.service.GetAuditTrailRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.tenant.profile.service.GetAuditTrailRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2037,
+  serialized_end=2077,
+)
+
+
+_GETSTATUSUPDATEAUDITTRAILRESPONSE = _descriptor.Descriptor(
+  name='GetStatusUpdateAuditTrailResponse',
+  full_name='org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2079,
+  serialized_end=2202,
+)
+
+
+_GETATTRIBUTEUPDATEAUDITTRAILRESPONSE = _descriptor.Descriptor(
+  name='GetAttributeUpdateAuditTrailResponse',
+  full_name='org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse.metadata', index=0,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2205,
+  serialized_end=2334,
+)
+
+
+_GETTENANTSREQUEST = _descriptor.Descriptor(
+  name='GetTenantsRequest',
+  full_name='org.apache.custos.tenant.profile.service.GetTenantsRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='offset', full_name='org.apache.custos.tenant.profile.service.GetTenantsRequest.offset', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='limit', full_name='org.apache.custos.tenant.profile.service.GetTenantsRequest.limit', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='parent_id', full_name='org.apache.custos.tenant.profile.service.GetTenantsRequest.parent_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.tenant.profile.service.GetTenantsRequest.status', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='requester_email', full_name='org.apache.custos.tenant.profile.service.GetTenantsRequest.requester_email', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2337,
+  serialized_end=2503,
+)
+
+_TENANT_JWKSENTRY.containing_type = _TENANT
+_TENANT.fields_by_name['tenant_status'].enum_type = _TENANTSTATUS
+_TENANT.fields_by_name['jwks'].message_type = _TENANT_JWKSENTRY
+_TENANTSTATUSUPDATEMETADATA.fields_by_name['updatedStatus'].enum_type = _TENANTSTATUS
+_UPDATETENANTRESPONSE.fields_by_name['tenant'].message_type = _TENANT
+_GETTENANTRESPONSE.fields_by_name['tenant'].message_type = _TENANT
+_GETALLTENANTSRESPONSE.fields_by_name['tenant'].message_type = _TENANT
+_GETALLTENANTSFORUSERRESPONSE.fields_by_name['tenant'].message_type = _TENANT
+_UPDATESTATUSREQUEST.fields_by_name['status'].enum_type = _TENANTSTATUS
+_UPDATESTATUSRESPONSE.fields_by_name['status'].enum_type = _TENANTSTATUS
+_GETSTATUSUPDATEAUDITTRAILRESPONSE.fields_by_name['metadata'].message_type = _TENANTSTATUSUPDATEMETADATA
+_GETATTRIBUTEUPDATEAUDITTRAILRESPONSE.fields_by_name['metadata'].message_type = _TENANTATTRIBUTEUPDATEMETADATA
+_GETTENANTSREQUEST.fields_by_name['status'].enum_type = _TENANTSTATUS
+DESCRIPTOR.message_types_by_name['Tenant'] = _TENANT
+DESCRIPTOR.message_types_by_name['TenantAttributeUpdateMetadata'] = _TENANTATTRIBUTEUPDATEMETADATA
+DESCRIPTOR.message_types_by_name['TenantStatusUpdateMetadata'] = _TENANTSTATUSUPDATEMETADATA
+DESCRIPTOR.message_types_by_name['AddTenantResponse'] = _ADDTENANTRESPONSE
+DESCRIPTOR.message_types_by_name['UpdateTenantResponse'] = _UPDATETENANTRESPONSE
+DESCRIPTOR.message_types_by_name['GetTenantRequest'] = _GETTENANTREQUEST
+DESCRIPTOR.message_types_by_name['GetTenantResponse'] = _GETTENANTRESPONSE
+DESCRIPTOR.message_types_by_name['GetAllTenantsResponse'] = _GETALLTENANTSRESPONSE
+DESCRIPTOR.message_types_by_name['IsTenantExistRequest'] = _ISTENANTEXISTREQUEST
+DESCRIPTOR.message_types_by_name['IsTenantExistResponse'] = _ISTENANTEXISTRESPONSE
+DESCRIPTOR.message_types_by_name['GetAllTenantsForUserRequest'] = _GETALLTENANTSFORUSERREQUEST
+DESCRIPTOR.message_types_by_name['GetAllTenantsForUserResponse'] = _GETALLTENANTSFORUSERRESPONSE
+DESCRIPTOR.message_types_by_name['UpdateStatusRequest'] = _UPDATESTATUSREQUEST
+DESCRIPTOR.message_types_by_name['UpdateStatusResponse'] = _UPDATESTATUSRESPONSE
+DESCRIPTOR.message_types_by_name['GetAuditTrailRequest'] = _GETAUDITTRAILREQUEST
+DESCRIPTOR.message_types_by_name['GetStatusUpdateAuditTrailResponse'] = _GETSTATUSUPDATEAUDITTRAILRESPONSE
+DESCRIPTOR.message_types_by_name['GetAttributeUpdateAuditTrailResponse'] = _GETATTRIBUTEUPDATEAUDITTRAILRESPONSE
+DESCRIPTOR.message_types_by_name['GetTenantsRequest'] = _GETTENANTSREQUEST
+DESCRIPTOR.enum_types_by_name['TenantStatus'] = _TENANTSTATUS
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Tenant = _reflection.GeneratedProtocolMessageType('Tenant', (_message.Message,), {
+
+  'JwksEntry' : _reflection.GeneratedProtocolMessageType('JwksEntry', (_message.Message,), {
+    'DESCRIPTOR' : _TENANT_JWKSENTRY,
+    '__module__' : 'TenantProfileService_pb2'
+    # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.Tenant.JwksEntry)
+    })
+  ,
+  'DESCRIPTOR' : _TENANT,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.Tenant)
+  })
+_sym_db.RegisterMessage(Tenant)
+_sym_db.RegisterMessage(Tenant.JwksEntry)
+
+TenantAttributeUpdateMetadata = _reflection.GeneratedProtocolMessageType('TenantAttributeUpdateMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _TENANTATTRIBUTEUPDATEMETADATA,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata)
+  })
+_sym_db.RegisterMessage(TenantAttributeUpdateMetadata)
+
+TenantStatusUpdateMetadata = _reflection.GeneratedProtocolMessageType('TenantStatusUpdateMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _TENANTSTATUSUPDATEMETADATA,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata)
+  })
+_sym_db.RegisterMessage(TenantStatusUpdateMetadata)
+
+AddTenantResponse = _reflection.GeneratedProtocolMessageType('AddTenantResponse', (_message.Message,), {
+  'DESCRIPTOR' : _ADDTENANTRESPONSE,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.AddTenantResponse)
+  })
+_sym_db.RegisterMessage(AddTenantResponse)
+
+UpdateTenantResponse = _reflection.GeneratedProtocolMessageType('UpdateTenantResponse', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATETENANTRESPONSE,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.UpdateTenantResponse)
+  })
+_sym_db.RegisterMessage(UpdateTenantResponse)
+
+GetTenantRequest = _reflection.GeneratedProtocolMessageType('GetTenantRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETTENANTREQUEST,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.GetTenantRequest)
+  })
+_sym_db.RegisterMessage(GetTenantRequest)
+
+GetTenantResponse = _reflection.GeneratedProtocolMessageType('GetTenantResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETTENANTRESPONSE,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.GetTenantResponse)
+  })
+_sym_db.RegisterMessage(GetTenantResponse)
+
+GetAllTenantsResponse = _reflection.GeneratedProtocolMessageType('GetAllTenantsResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLTENANTSRESPONSE,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.GetAllTenantsResponse)
+  })
+_sym_db.RegisterMessage(GetAllTenantsResponse)
+
+IsTenantExistRequest = _reflection.GeneratedProtocolMessageType('IsTenantExistRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ISTENANTEXISTREQUEST,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.IsTenantExistRequest)
+  })
+_sym_db.RegisterMessage(IsTenantExistRequest)
+
+IsTenantExistResponse = _reflection.GeneratedProtocolMessageType('IsTenantExistResponse', (_message.Message,), {
+  'DESCRIPTOR' : _ISTENANTEXISTRESPONSE,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.IsTenantExistResponse)
+  })
+_sym_db.RegisterMessage(IsTenantExistResponse)
+
+GetAllTenantsForUserRequest = _reflection.GeneratedProtocolMessageType('GetAllTenantsForUserRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLTENANTSFORUSERREQUEST,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest)
+  })
+_sym_db.RegisterMessage(GetAllTenantsForUserRequest)
+
+GetAllTenantsForUserResponse = _reflection.GeneratedProtocolMessageType('GetAllTenantsForUserResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLTENANTSFORUSERRESPONSE,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse)
+  })
+_sym_db.RegisterMessage(GetAllTenantsForUserResponse)
+
+UpdateStatusRequest = _reflection.GeneratedProtocolMessageType('UpdateStatusRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATESTATUSREQUEST,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.UpdateStatusRequest)
+  })
+_sym_db.RegisterMessage(UpdateStatusRequest)
+
+UpdateStatusResponse = _reflection.GeneratedProtocolMessageType('UpdateStatusResponse', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATESTATUSRESPONSE,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.UpdateStatusResponse)
+  })
+_sym_db.RegisterMessage(UpdateStatusResponse)
+
+GetAuditTrailRequest = _reflection.GeneratedProtocolMessageType('GetAuditTrailRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETAUDITTRAILREQUEST,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.GetAuditTrailRequest)
+  })
+_sym_db.RegisterMessage(GetAuditTrailRequest)
+
+GetStatusUpdateAuditTrailResponse = _reflection.GeneratedProtocolMessageType('GetStatusUpdateAuditTrailResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETSTATUSUPDATEAUDITTRAILRESPONSE,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse)
+  })
+_sym_db.RegisterMessage(GetStatusUpdateAuditTrailResponse)
+
+GetAttributeUpdateAuditTrailResponse = _reflection.GeneratedProtocolMessageType('GetAttributeUpdateAuditTrailResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETATTRIBUTEUPDATEAUDITTRAILRESPONSE,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse)
+  })
+_sym_db.RegisterMessage(GetAttributeUpdateAuditTrailResponse)
+
+GetTenantsRequest = _reflection.GeneratedProtocolMessageType('GetTenantsRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETTENANTSREQUEST,
+  '__module__' : 'TenantProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.profile.service.GetTenantsRequest)
+  })
+_sym_db.RegisterMessage(GetTenantsRequest)
+
+
+DESCRIPTOR._options = None
+_TENANT_JWKSENTRY._options = None
+
+_TENANTPROFILESERVICE = _descriptor.ServiceDescriptor(
+  name='TenantProfileService',
+  full_name='org.apache.custos.tenant.profile.service.TenantProfileService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=2607,
+  serialized_end=3962,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='addTenant',
+    full_name='org.apache.custos.tenant.profile.service.TenantProfileService.addTenant',
+    index=0,
+    containing_service=None,
+    input_type=_TENANT,
+    output_type=_TENANT,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateTenant',
+    full_name='org.apache.custos.tenant.profile.service.TenantProfileService.updateTenant',
+    index=1,
+    containing_service=None,
+    input_type=_TENANT,
+    output_type=_TENANT,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getTenant',
+    full_name='org.apache.custos.tenant.profile.service.TenantProfileService.getTenant',
+    index=2,
+    containing_service=None,
+    input_type=_GETTENANTREQUEST,
+    output_type=_GETTENANTRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateTenantStatus',
+    full_name='org.apache.custos.tenant.profile.service.TenantProfileService.updateTenantStatus',
+    index=3,
+    containing_service=None,
+    input_type=_UPDATESTATUSREQUEST,
+    output_type=_UPDATESTATUSRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllTenants',
+    full_name='org.apache.custos.tenant.profile.service.TenantProfileService.getAllTenants',
+    index=4,
+    containing_service=None,
+    input_type=_GETTENANTSREQUEST,
+    output_type=_GETALLTENANTSRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isTenantExist',
+    full_name='org.apache.custos.tenant.profile.service.TenantProfileService.isTenantExist',
+    index=5,
+    containing_service=None,
+    input_type=_ISTENANTEXISTREQUEST,
+    output_type=_ISTENANTEXISTRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllTenantsForUser',
+    full_name='org.apache.custos.tenant.profile.service.TenantProfileService.getAllTenantsForUser',
+    index=6,
+    containing_service=None,
+    input_type=_GETALLTENANTSFORUSERREQUEST,
+    output_type=_GETALLTENANTSFORUSERRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getTenantStatusUpdateAuditTrail',
+    full_name='org.apache.custos.tenant.profile.service.TenantProfileService.getTenantStatusUpdateAuditTrail',
+    index=7,
+    containing_service=None,
+    input_type=_GETAUDITTRAILREQUEST,
+    output_type=_GETSTATUSUPDATEAUDITTRAILRESPONSE,
+    serialized_options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getTenantAttributeUpdateAuditTrail',
+    full_name='org.apache.custos.tenant.profile.service.TenantProfileService.getTenantAttributeUpdateAuditTrail',
+    index=8,
+    containing_service=None,
+    input_type=_GETAUDITTRAILREQUEST,
+    output_type=_GETATTRIBUTEUPDATEAUDITTRAILRESPONSE,
+    serialized_options=None,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_TENANTPROFILESERVICE)
+
+DESCRIPTOR.services_by_name['TenantProfileService'] = _TENANTPROFILESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/TenantProfileService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/TenantProfileService_pb2_grpc.py
new file mode 100644
index 0000000..fceff5b
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/TenantProfileService_pb2_grpc.py
@@ -0,0 +1,182 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import TenantProfileService_pb2 as TenantProfileService__pb2
+
+
+class TenantProfileServiceStub(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.addTenant = channel.unary_unary(
+        '/org.apache.custos.tenant.profile.service.TenantProfileService/addTenant',
+        request_serializer=TenantProfileService__pb2.Tenant.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.Tenant.FromString,
+        )
+    self.updateTenant = channel.unary_unary(
+        '/org.apache.custos.tenant.profile.service.TenantProfileService/updateTenant',
+        request_serializer=TenantProfileService__pb2.Tenant.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.Tenant.FromString,
+        )
+    self.getTenant = channel.unary_unary(
+        '/org.apache.custos.tenant.profile.service.TenantProfileService/getTenant',
+        request_serializer=TenantProfileService__pb2.GetTenantRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetTenantResponse.FromString,
+        )
+    self.updateTenantStatus = channel.unary_unary(
+        '/org.apache.custos.tenant.profile.service.TenantProfileService/updateTenantStatus',
+        request_serializer=TenantProfileService__pb2.UpdateStatusRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.UpdateStatusResponse.FromString,
+        )
+    self.getAllTenants = channel.unary_unary(
+        '/org.apache.custos.tenant.profile.service.TenantProfileService/getAllTenants',
+        request_serializer=TenantProfileService__pb2.GetTenantsRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetAllTenantsResponse.FromString,
+        )
+    self.isTenantExist = channel.unary_unary(
+        '/org.apache.custos.tenant.profile.service.TenantProfileService/isTenantExist',
+        request_serializer=TenantProfileService__pb2.IsTenantExistRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.IsTenantExistResponse.FromString,
+        )
+    self.getAllTenantsForUser = channel.unary_unary(
+        '/org.apache.custos.tenant.profile.service.TenantProfileService/getAllTenantsForUser',
+        request_serializer=TenantProfileService__pb2.GetAllTenantsForUserRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetAllTenantsForUserResponse.FromString,
+        )
+    self.getTenantStatusUpdateAuditTrail = channel.unary_unary(
+        '/org.apache.custos.tenant.profile.service.TenantProfileService/getTenantStatusUpdateAuditTrail',
+        request_serializer=TenantProfileService__pb2.GetAuditTrailRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetStatusUpdateAuditTrailResponse.FromString,
+        )
+    self.getTenantAttributeUpdateAuditTrail = channel.unary_unary(
+        '/org.apache.custos.tenant.profile.service.TenantProfileService/getTenantAttributeUpdateAuditTrail',
+        request_serializer=TenantProfileService__pb2.GetAuditTrailRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetAttributeUpdateAuditTrailResponse.FromString,
+        )
+
+
+class TenantProfileServiceServicer(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def addTenant(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def updateTenant(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getTenant(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def updateTenantStatus(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAllTenants(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def isTenantExist(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAllTenantsForUser(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getTenantStatusUpdateAuditTrail(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getTenantAttributeUpdateAuditTrail(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_TenantProfileServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'addTenant': grpc.unary_unary_rpc_method_handler(
+          servicer.addTenant,
+          request_deserializer=TenantProfileService__pb2.Tenant.FromString,
+          response_serializer=TenantProfileService__pb2.Tenant.SerializeToString,
+      ),
+      'updateTenant': grpc.unary_unary_rpc_method_handler(
+          servicer.updateTenant,
+          request_deserializer=TenantProfileService__pb2.Tenant.FromString,
+          response_serializer=TenantProfileService__pb2.Tenant.SerializeToString,
+      ),
+      'getTenant': grpc.unary_unary_rpc_method_handler(
+          servicer.getTenant,
+          request_deserializer=TenantProfileService__pb2.GetTenantRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetTenantResponse.SerializeToString,
+      ),
+      'updateTenantStatus': grpc.unary_unary_rpc_method_handler(
+          servicer.updateTenantStatus,
+          request_deserializer=TenantProfileService__pb2.UpdateStatusRequest.FromString,
+          response_serializer=TenantProfileService__pb2.UpdateStatusResponse.SerializeToString,
+      ),
+      'getAllTenants': grpc.unary_unary_rpc_method_handler(
+          servicer.getAllTenants,
+          request_deserializer=TenantProfileService__pb2.GetTenantsRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetAllTenantsResponse.SerializeToString,
+      ),
+      'isTenantExist': grpc.unary_unary_rpc_method_handler(
+          servicer.isTenantExist,
+          request_deserializer=TenantProfileService__pb2.IsTenantExistRequest.FromString,
+          response_serializer=TenantProfileService__pb2.IsTenantExistResponse.SerializeToString,
+      ),
+      'getAllTenantsForUser': grpc.unary_unary_rpc_method_handler(
+          servicer.getAllTenantsForUser,
+          request_deserializer=TenantProfileService__pb2.GetAllTenantsForUserRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetAllTenantsForUserResponse.SerializeToString,
+      ),
+      'getTenantStatusUpdateAuditTrail': grpc.unary_unary_rpc_method_handler(
+          servicer.getTenantStatusUpdateAuditTrail,
+          request_deserializer=TenantProfileService__pb2.GetAuditTrailRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetStatusUpdateAuditTrailResponse.SerializeToString,
+      ),
+      'getTenantAttributeUpdateAuditTrail': grpc.unary_unary_rpc_method_handler(
+          servicer.getTenantAttributeUpdateAuditTrail,
+          request_deserializer=TenantProfileService__pb2.GetAuditTrailRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetAttributeUpdateAuditTrailResponse.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.custos.tenant.profile.service.TenantProfileService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/UserProfileService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/core/UserProfileService_pb2.py
new file mode 100644
index 0000000..7051840
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/UserProfileService_pb2.py
@@ -0,0 +1,1421 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: UserProfileService.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='UserProfileService.proto',
+  package='org.apache.custos.user.profile.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x18UserProfileService.proto\x12&org.apache.custos.user.profile.service\"\xdc\x03\n\x0bUserProfile\x12\x10\n\x08username\x18\x01 \x01(\t\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x12\n\nfirst_name\x18\x03 \x01(\t\x12\x11\n\tlast_name\x18\x04 \x01(\t\x12\x12\n\ncreated_at\x18\x05 \x01(\x03\x12\x42\n\x06status\x18\x06 \x01(\x0e\x32\x32.org.apache.custos.user.profile.service.UserStatus\x12I\n\nattributes\x18\x07 \x03(\x0b\x32\x35.org.apache.custos.user.profile.service.UserAttribute\x12\x14\n\x0c\x63lient_roles\x18\x08 \x03(\t\x12\x13\n\x0brealm_roles\x18\t \x03(\t\x12\x18\n\x10last_modified_at\x18\n \x01(\x03\x12?\n\x04type\x18\x0b \x01(\x0e\x32\x31.org.apache.custos.user.profile.service.UserTypes\x12\\\n\x0fmembership_type\x18\x0c \x01(\x0e\x32\x43.org.apache.custos.user.profile.service.DefaultGroupMembershipTypes\"\x93\x01\n\x12UserProfileRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x44\n\x07profile\x18\x02 \x01(\x0b\x32\x33.org.apache.custos.user.profile.service.UserProfile\x12\x13\n\x0bperformedBy\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\"7\n\rUserAttribute\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x03(\t\"c\n\x1aGetAllUserProfilesResponse\x12\x45\n\x08profiles\x18\x01 \x03(\x0b\x32\x33.org.apache.custos.user.profile.service.UserProfile\"@\n\x1aGetUpdateAuditTrailRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x10\n\x08username\x18\x02 \x01(\t\"\x83\x01\n\"UserProfileAttributeUpdateMetadata\x12\x18\n\x10updatedAttribute\x18\x01 \x01(\t\x12\x1d\n\x15updatedAttributeValue\x18\x02 \x01(\t\x12\x11\n\tupdatedBy\x18\x03 \x01(\t\x12\x11\n\tupdatedAt\x18\x04 \x01(\t\"\x92\x01\n\x1fUserProfileStatusUpdateMetadata\x12I\n\rupdatedStatus\x18\x01 \x01(\x0e\x32\x32.org.apache.custos.user.profile.service.UserStatus\x12\x11\n\tupdatedBy\x18\x02 \x01(\t\x12\x11\n\tupdatedAt\x18\x03 \x01(\t\"\xdf\x01\n\x1bGetUpdateAuditTrailResponse\x12\x62\n\x0e\x61ttributeAudit\x18\x01 \x03(\x0b\x32J.org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata\x12\\\n\x0bstatusAudit\x18\x02 \x03(\x0b\x32G.org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata\"\xe3\x01\n\x0cGroupRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12<\n\x05group\x18\x02 \x01(\x0b\x32-.org.apache.custos.user.profile.service.Group\x12\x13\n\x0bperformedBy\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\\\n\x0fmembership_type\x18\x05 \x01(\x0e\x32\x43.org.apache.custos.user.profile.service.DefaultGroupMembershipTypes\"U\n\x14GetAllGroupsResponse\x12=\n\x06groups\x18\x01 \x03(\x0b\x32-.org.apache.custos.user.profile.service.Group\"\x84\x02\n\x05Group\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0brealm_roles\x18\x03 \x03(\t\x12\x14\n\x0c\x63lient_roles\x18\x04 \x03(\t\x12\x11\n\tparent_id\x18\x05 \x01(\t\x12\x14\n\x0c\x63reated_time\x18\x06 \x01(\x03\x12\x1a\n\x12last_modified_time\x18\x07 \x01(\x03\x12J\n\nattributes\x18\x08 \x03(\x0b\x32\x36.org.apache.custos.user.profile.service.GroupAttribute\x12\x13\n\x0b\x64\x65scription\x18\t \x01(\t\x12\x10\n\x08owner_id\x18\n \x01(\t\"8\n\x0eGroupAttribute\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x03(\t\"g\n\x0fGroupMembership\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x10\n\x08group_id\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x0c\n\x04type\x18\x04 \x01(\t\x12\x10\n\x08\x63lientId\x18\x05 \x01(\t\"b\n\x16GroupToGroupMembership\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x11\n\tparent_id\x18\x02 \x01(\t\x12\x10\n\x08\x63hild_id\x18\x03 \x01(\t\x12\x11\n\tclient_id\x18\x04 \x01(\t\"\x18\n\x06Status\x12\x0e\n\x06status\x18\x01 \x01(\x08\".\n\x1eUserGroupMembershipTypeRequest\x12\x0c\n\x04type\x18\x01 \x01(\t*\xe3\x01\n\nUserStatus\x12\n\n\x06\x41\x43TIVE\x10\x00\x12\r\n\tCONFIRMED\x10\x01\x12\x0c\n\x08\x41PPROVED\x10\x02\x12\x0b\n\x07\x44\x45LETED\x10\x03\x12\r\n\tDUPLICATE\x10\x04\x12\x10\n\x0cGRACE_PERIOD\x10\x05\x12\x0b\n\x07INVITED\x10\x06\x12\n\n\x06\x44\x45NIED\x10\x07\x12\x0b\n\x07PENDING\x10\x08\x12\x14\n\x10PENDING_APPROVAL\x10\t\x12\x18\n\x14PENDING_CONFIRMATION\x10\n\x12\r\n\tSUSPENDED\x10\x0b\x12\x0c\n\x08\x44\x45\x43LINED\x10\x0c\x12\x0b\n\x07\x45XPIRED\x10\r*?\n\x1b\x44\x65\x66\x61ultGroupMembershipTypes\x12\t\n\x05OWNER\x10\x00\x12\t\n\x05\x41\x44MIN\x10\x01\x12\n\n\x06MEMBER\x10\x02*(\n\tUserTypes\x12\x0c\n\x08\x45ND_USER\x10\x00\x12\r\n\tCOMMUNITY\x10\x01\x32\xed\x19\n\x12UserProfileService\x12\x84\x01\n\x11\x63reateUserProfile\x12:.org.apache.custos.user.profile.service.UserProfileRequest\x1a\x33.org.apache.custos.user.profile.service.UserProfile\x12\x84\x01\n\x11updateUserProfile\x12:.org.apache.custos.user.profile.service.UserProfileRequest\x1a\x33.org.apache.custos.user.profile.service.UserProfile\x12\x81\x01\n\x0egetUserProfile\x12:.org.apache.custos.user.profile.service.UserProfileRequest\x1a\x33.org.apache.custos.user.profile.service.UserProfile\x12\x84\x01\n\x11\x64\x65leteUserProfile\x12:.org.apache.custos.user.profile.service.UserProfileRequest\x1a\x33.org.apache.custos.user.profile.service.UserProfile\x12\x9c\x01\n\x1agetAllUserProfilesInTenant\x12:.org.apache.custos.user.profile.service.UserProfileRequest\x1a\x42.org.apache.custos.user.profile.service.GetAllUserProfilesResponse\x12\x9e\x01\n\x1c\x66indUserProfilesByAttributes\x12:.org.apache.custos.user.profile.service.UserProfileRequest\x1a\x42.org.apache.custos.user.profile.service.GetAllUserProfilesResponse\x12r\n\x0b\x63reateGroup\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a-.org.apache.custos.user.profile.service.Group\x12r\n\x0bupdateGroup\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a-.org.apache.custos.user.profile.service.Group\x12r\n\x0b\x64\x65leteGroup\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a-.org.apache.custos.user.profile.service.Group\x12o\n\x08getGroup\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a-.org.apache.custos.user.profile.service.Group\x12\x82\x01\n\x0cgetAllGroups\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a<.org.apache.custos.user.profile.service.GetAllGroupsResponse\x12\xa4\x01\n\x19getUserProfileAuditTrails\x12\x42.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest\x1a\x43.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse\x12y\n\x0e\x61\x64\x64UserToGroup\x12\x37.org.apache.custos.user.profile.service.GroupMembership\x1a..org.apache.custos.user.profile.service.Status\x12~\n\x13removeUserFromGroup\x12\x37.org.apache.custos.user.profile.service.GroupMembership\x1a..org.apache.custos.user.profile.service.Status\x12\x8c\x01\n\x1a\x61\x64\x64\x43hildGroupToParentGroup\x12>.org.apache.custos.user.profile.service.GroupToGroupMembership\x1a..org.apache.custos.user.profile.service.Status\x12\x91\x01\n\x1fremoveChildGroupFromParentGroup\x12>.org.apache.custos.user.profile.service.GroupToGroupMembership\x1a..org.apache.custos.user.profile.service.Status\x12\x8e\x01\n\x12getAllGroupsOfUser\x12:.org.apache.custos.user.profile.service.UserProfileRequest\x1a<.org.apache.custos.user.profile.service.GetAllGroupsResponse\x12\x8f\x01\n\x19getAllParentGroupsOfGroup\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a<.org.apache.custos.user.profile.service.GetAllGroupsResponse\x12\x94\x01\n\x1a\x61\x64\x64UserGroupMembershipType\x12\x46.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest\x1a..org.apache.custos.user.profile.service.Status\x12\x97\x01\n\x1dremoveUserGroupMembershipType\x12\x46.org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest\x1a..org.apache.custos.user.profile.service.Status\x12\x8c\x01\n\x10getAllChildUsers\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a\x42.org.apache.custos.user.profile.service.GetAllUserProfilesResponse\x12\x87\x01\n\x11getAllChildGroups\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a<.org.apache.custos.user.profile.service.GetAllGroupsResponse\x12\x83\x01\n\x18\x63hangeUserMembershipType\x12\x37.org.apache.custos.user.profile.service.GroupMembership\x1a..org.apache.custos.user.profile.service.Status\x12t\n\thasAccess\x12\x37.org.apache.custos.user.profile.service.GroupMembership\x1a..org.apache.custos.user.profile.service.StatusB\x02P\x01\x62\x06proto3'
+)
+
+_USERSTATUS = _descriptor.EnumDescriptor(
+  name='UserStatus',
+  full_name='org.apache.custos.user.profile.service.UserStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='ACTIVE', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIRMED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='APPROVED', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DELETED', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DUPLICATE', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='GRACE_PERIOD', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='INVITED', index=6, number=6,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DENIED', index=7, number=7,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='PENDING', index=8, number=8,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='PENDING_APPROVAL', index=9, number=9,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='PENDING_CONFIRMATION', index=10, number=10,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SUSPENDED', index=11, number=11,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DECLINED', index=12, number=12,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EXPIRED', index=13, number=13,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=2348,
+  serialized_end=2575,
+)
+_sym_db.RegisterEnumDescriptor(_USERSTATUS)
+
+UserStatus = enum_type_wrapper.EnumTypeWrapper(_USERSTATUS)
+_DEFAULTGROUPMEMBERSHIPTYPES = _descriptor.EnumDescriptor(
+  name='DefaultGroupMembershipTypes',
+  full_name='org.apache.custos.user.profile.service.DefaultGroupMembershipTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='OWNER', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='ADMIN', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='MEMBER', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=2577,
+  serialized_end=2640,
+)
+_sym_db.RegisterEnumDescriptor(_DEFAULTGROUPMEMBERSHIPTYPES)
+
+DefaultGroupMembershipTypes = enum_type_wrapper.EnumTypeWrapper(_DEFAULTGROUPMEMBERSHIPTYPES)
+_USERTYPES = _descriptor.EnumDescriptor(
+  name='UserTypes',
+  full_name='org.apache.custos.user.profile.service.UserTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='END_USER', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='COMMUNITY', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=2642,
+  serialized_end=2682,
+)
+_sym_db.RegisterEnumDescriptor(_USERTYPES)
+
+UserTypes = enum_type_wrapper.EnumTypeWrapper(_USERTYPES)
+ACTIVE = 0
+CONFIRMED = 1
+APPROVED = 2
+DELETED = 3
+DUPLICATE = 4
+GRACE_PERIOD = 5
+INVITED = 6
+DENIED = 7
+PENDING = 8
+PENDING_APPROVAL = 9
+PENDING_CONFIRMATION = 10
+SUSPENDED = 11
+DECLINED = 12
+EXPIRED = 13
+OWNER = 0
+ADMIN = 1
+MEMBER = 2
+END_USER = 0
+COMMUNITY = 1
+
+
+
+_USERPROFILE = _descriptor.Descriptor(
+  name='UserProfile',
+  full_name='org.apache.custos.user.profile.service.UserProfile',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.user.profile.service.UserProfile.username', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='email', full_name='org.apache.custos.user.profile.service.UserProfile.email', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='first_name', full_name='org.apache.custos.user.profile.service.UserProfile.first_name', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_name', full_name='org.apache.custos.user.profile.service.UserProfile.last_name', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='created_at', full_name='org.apache.custos.user.profile.service.UserProfile.created_at', index=4,
+      number=5, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.user.profile.service.UserProfile.status', index=5,
+      number=6, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.user.profile.service.UserProfile.attributes', index=6,
+      number=7, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.user.profile.service.UserProfile.client_roles', index=7,
+      number=8, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='realm_roles', full_name='org.apache.custos.user.profile.service.UserProfile.realm_roles', index=8,
+      number=9, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_modified_at', full_name='org.apache.custos.user.profile.service.UserProfile.last_modified_at', index=9,
+      number=10, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.user.profile.service.UserProfile.type', index=10,
+      number=11, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='membership_type', full_name='org.apache.custos.user.profile.service.UserProfile.membership_type', index=11,
+      number=12, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=69,
+  serialized_end=545,
+)
+
+
+_USERPROFILEREQUEST = _descriptor.Descriptor(
+  name='UserProfileRequest',
+  full_name='org.apache.custos.user.profile.service.UserProfileRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.profile.service.UserProfileRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='profile', full_name='org.apache.custos.user.profile.service.UserProfileRequest.profile', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.user.profile.service.UserProfileRequest.performedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.user.profile.service.UserProfileRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=548,
+  serialized_end=695,
+)
+
+
+_USERATTRIBUTE = _descriptor.Descriptor(
+  name='UserAttribute',
+  full_name='org.apache.custos.user.profile.service.UserAttribute',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.user.profile.service.UserAttribute.id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.user.profile.service.UserAttribute.key', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.user.profile.service.UserAttribute.value', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=697,
+  serialized_end=752,
+)
+
+
+_GETALLUSERPROFILESRESPONSE = _descriptor.Descriptor(
+  name='GetAllUserProfilesResponse',
+  full_name='org.apache.custos.user.profile.service.GetAllUserProfilesResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='profiles', full_name='org.apache.custos.user.profile.service.GetAllUserProfilesResponse.profiles', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=754,
+  serialized_end=853,
+)
+
+
+_GETUPDATEAUDITTRAILREQUEST = _descriptor.Descriptor(
+  name='GetUpdateAuditTrailRequest',
+  full_name='org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest.username', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=855,
+  serialized_end=919,
+)
+
+
+_USERPROFILEATTRIBUTEUPDATEMETADATA = _descriptor.Descriptor(
+  name='UserProfileAttributeUpdateMetadata',
+  full_name='org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='updatedAttribute', full_name='org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.updatedAttribute', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='updatedAttributeValue', full_name='org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.updatedAttributeValue', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='updatedBy', full_name='org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.updatedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='updatedAt', full_name='org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata.updatedAt', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=922,
+  serialized_end=1053,
+)
+
+
+_USERPROFILESTATUSUPDATEMETADATA = _descriptor.Descriptor(
+  name='UserProfileStatusUpdateMetadata',
+  full_name='org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='updatedStatus', full_name='org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.updatedStatus', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='updatedBy', full_name='org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.updatedBy', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='updatedAt', full_name='org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata.updatedAt', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1056,
+  serialized_end=1202,
+)
+
+
+_GETUPDATEAUDITTRAILRESPONSE = _descriptor.Descriptor(
+  name='GetUpdateAuditTrailResponse',
+  full_name='org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='attributeAudit', full_name='org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.attributeAudit', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='statusAudit', full_name='org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse.statusAudit', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1205,
+  serialized_end=1428,
+)
+
+
+_GROUPREQUEST = _descriptor.Descriptor(
+  name='GroupRequest',
+  full_name='org.apache.custos.user.profile.service.GroupRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.profile.service.GroupRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='group', full_name='org.apache.custos.user.profile.service.GroupRequest.group', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.user.profile.service.GroupRequest.performedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.user.profile.service.GroupRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='membership_type', full_name='org.apache.custos.user.profile.service.GroupRequest.membership_type', index=4,
+      number=5, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1431,
+  serialized_end=1658,
+)
+
+
+_GETALLGROUPSRESPONSE = _descriptor.Descriptor(
+  name='GetAllGroupsResponse',
+  full_name='org.apache.custos.user.profile.service.GetAllGroupsResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='groups', full_name='org.apache.custos.user.profile.service.GetAllGroupsResponse.groups', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1660,
+  serialized_end=1745,
+)
+
+
+_GROUP = _descriptor.Descriptor(
+  name='Group',
+  full_name='org.apache.custos.user.profile.service.Group',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.user.profile.service.Group.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.user.profile.service.Group.name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='realm_roles', full_name='org.apache.custos.user.profile.service.Group.realm_roles', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.user.profile.service.Group.client_roles', index=3,
+      number=4, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='parent_id', full_name='org.apache.custos.user.profile.service.Group.parent_id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='created_time', full_name='org.apache.custos.user.profile.service.Group.created_time', index=5,
+      number=6, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_modified_time', full_name='org.apache.custos.user.profile.service.Group.last_modified_time', index=6,
+      number=7, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.user.profile.service.Group.attributes', index=7,
+      number=8, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='org.apache.custos.user.profile.service.Group.description', index=8,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='owner_id', full_name='org.apache.custos.user.profile.service.Group.owner_id', index=9,
+      number=10, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1748,
+  serialized_end=2008,
+)
+
+
+_GROUPATTRIBUTE = _descriptor.Descriptor(
+  name='GroupAttribute',
+  full_name='org.apache.custos.user.profile.service.GroupAttribute',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.user.profile.service.GroupAttribute.id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.user.profile.service.GroupAttribute.key', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.user.profile.service.GroupAttribute.value', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2010,
+  serialized_end=2066,
+)
+
+
+_GROUPMEMBERSHIP = _descriptor.Descriptor(
+  name='GroupMembership',
+  full_name='org.apache.custos.user.profile.service.GroupMembership',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.profile.service.GroupMembership.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='group_id', full_name='org.apache.custos.user.profile.service.GroupMembership.group_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.user.profile.service.GroupMembership.username', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.user.profile.service.GroupMembership.type', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.user.profile.service.GroupMembership.clientId', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2068,
+  serialized_end=2171,
+)
+
+
+_GROUPTOGROUPMEMBERSHIP = _descriptor.Descriptor(
+  name='GroupToGroupMembership',
+  full_name='org.apache.custos.user.profile.service.GroupToGroupMembership',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.profile.service.GroupToGroupMembership.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='parent_id', full_name='org.apache.custos.user.profile.service.GroupToGroupMembership.parent_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='child_id', full_name='org.apache.custos.user.profile.service.GroupToGroupMembership.child_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.user.profile.service.GroupToGroupMembership.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2173,
+  serialized_end=2271,
+)
+
+
+_STATUS = _descriptor.Descriptor(
+  name='Status',
+  full_name='org.apache.custos.user.profile.service.Status',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.user.profile.service.Status.status', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2273,
+  serialized_end=2297,
+)
+
+
+_USERGROUPMEMBERSHIPTYPEREQUEST = _descriptor.Descriptor(
+  name='UserGroupMembershipTypeRequest',
+  full_name='org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest.type', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2299,
+  serialized_end=2345,
+)
+
+_USERPROFILE.fields_by_name['status'].enum_type = _USERSTATUS
+_USERPROFILE.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_USERPROFILE.fields_by_name['type'].enum_type = _USERTYPES
+_USERPROFILE.fields_by_name['membership_type'].enum_type = _DEFAULTGROUPMEMBERSHIPTYPES
+_USERPROFILEREQUEST.fields_by_name['profile'].message_type = _USERPROFILE
+_GETALLUSERPROFILESRESPONSE.fields_by_name['profiles'].message_type = _USERPROFILE
+_USERPROFILESTATUSUPDATEMETADATA.fields_by_name['updatedStatus'].enum_type = _USERSTATUS
+_GETUPDATEAUDITTRAILRESPONSE.fields_by_name['attributeAudit'].message_type = _USERPROFILEATTRIBUTEUPDATEMETADATA
+_GETUPDATEAUDITTRAILRESPONSE.fields_by_name['statusAudit'].message_type = _USERPROFILESTATUSUPDATEMETADATA
+_GROUPREQUEST.fields_by_name['group'].message_type = _GROUP
+_GROUPREQUEST.fields_by_name['membership_type'].enum_type = _DEFAULTGROUPMEMBERSHIPTYPES
+_GETALLGROUPSRESPONSE.fields_by_name['groups'].message_type = _GROUP
+_GROUP.fields_by_name['attributes'].message_type = _GROUPATTRIBUTE
+DESCRIPTOR.message_types_by_name['UserProfile'] = _USERPROFILE
+DESCRIPTOR.message_types_by_name['UserProfileRequest'] = _USERPROFILEREQUEST
+DESCRIPTOR.message_types_by_name['UserAttribute'] = _USERATTRIBUTE
+DESCRIPTOR.message_types_by_name['GetAllUserProfilesResponse'] = _GETALLUSERPROFILESRESPONSE
+DESCRIPTOR.message_types_by_name['GetUpdateAuditTrailRequest'] = _GETUPDATEAUDITTRAILREQUEST
+DESCRIPTOR.message_types_by_name['UserProfileAttributeUpdateMetadata'] = _USERPROFILEATTRIBUTEUPDATEMETADATA
+DESCRIPTOR.message_types_by_name['UserProfileStatusUpdateMetadata'] = _USERPROFILESTATUSUPDATEMETADATA
+DESCRIPTOR.message_types_by_name['GetUpdateAuditTrailResponse'] = _GETUPDATEAUDITTRAILRESPONSE
+DESCRIPTOR.message_types_by_name['GroupRequest'] = _GROUPREQUEST
+DESCRIPTOR.message_types_by_name['GetAllGroupsResponse'] = _GETALLGROUPSRESPONSE
+DESCRIPTOR.message_types_by_name['Group'] = _GROUP
+DESCRIPTOR.message_types_by_name['GroupAttribute'] = _GROUPATTRIBUTE
+DESCRIPTOR.message_types_by_name['GroupMembership'] = _GROUPMEMBERSHIP
+DESCRIPTOR.message_types_by_name['GroupToGroupMembership'] = _GROUPTOGROUPMEMBERSHIP
+DESCRIPTOR.message_types_by_name['Status'] = _STATUS
+DESCRIPTOR.message_types_by_name['UserGroupMembershipTypeRequest'] = _USERGROUPMEMBERSHIPTYPEREQUEST
+DESCRIPTOR.enum_types_by_name['UserStatus'] = _USERSTATUS
+DESCRIPTOR.enum_types_by_name['DefaultGroupMembershipTypes'] = _DEFAULTGROUPMEMBERSHIPTYPES
+DESCRIPTOR.enum_types_by_name['UserTypes'] = _USERTYPES
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+UserProfile = _reflection.GeneratedProtocolMessageType('UserProfile', (_message.Message,), {
+  'DESCRIPTOR' : _USERPROFILE,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.UserProfile)
+  })
+_sym_db.RegisterMessage(UserProfile)
+
+UserProfileRequest = _reflection.GeneratedProtocolMessageType('UserProfileRequest', (_message.Message,), {
+  'DESCRIPTOR' : _USERPROFILEREQUEST,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.UserProfileRequest)
+  })
+_sym_db.RegisterMessage(UserProfileRequest)
+
+UserAttribute = _reflection.GeneratedProtocolMessageType('UserAttribute', (_message.Message,), {
+  'DESCRIPTOR' : _USERATTRIBUTE,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.UserAttribute)
+  })
+_sym_db.RegisterMessage(UserAttribute)
+
+GetAllUserProfilesResponse = _reflection.GeneratedProtocolMessageType('GetAllUserProfilesResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLUSERPROFILESRESPONSE,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.GetAllUserProfilesResponse)
+  })
+_sym_db.RegisterMessage(GetAllUserProfilesResponse)
+
+GetUpdateAuditTrailRequest = _reflection.GeneratedProtocolMessageType('GetUpdateAuditTrailRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETUPDATEAUDITTRAILREQUEST,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest)
+  })
+_sym_db.RegisterMessage(GetUpdateAuditTrailRequest)
+
+UserProfileAttributeUpdateMetadata = _reflection.GeneratedProtocolMessageType('UserProfileAttributeUpdateMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _USERPROFILEATTRIBUTEUPDATEMETADATA,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata)
+  })
+_sym_db.RegisterMessage(UserProfileAttributeUpdateMetadata)
+
+UserProfileStatusUpdateMetadata = _reflection.GeneratedProtocolMessageType('UserProfileStatusUpdateMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _USERPROFILESTATUSUPDATEMETADATA,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata)
+  })
+_sym_db.RegisterMessage(UserProfileStatusUpdateMetadata)
+
+GetUpdateAuditTrailResponse = _reflection.GeneratedProtocolMessageType('GetUpdateAuditTrailResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETUPDATEAUDITTRAILRESPONSE,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse)
+  })
+_sym_db.RegisterMessage(GetUpdateAuditTrailResponse)
+
+GroupRequest = _reflection.GeneratedProtocolMessageType('GroupRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPREQUEST,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.GroupRequest)
+  })
+_sym_db.RegisterMessage(GroupRequest)
+
+GetAllGroupsResponse = _reflection.GeneratedProtocolMessageType('GetAllGroupsResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLGROUPSRESPONSE,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.GetAllGroupsResponse)
+  })
+_sym_db.RegisterMessage(GetAllGroupsResponse)
+
+Group = _reflection.GeneratedProtocolMessageType('Group', (_message.Message,), {
+  'DESCRIPTOR' : _GROUP,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.Group)
+  })
+_sym_db.RegisterMessage(Group)
+
+GroupAttribute = _reflection.GeneratedProtocolMessageType('GroupAttribute', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPATTRIBUTE,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.GroupAttribute)
+  })
+_sym_db.RegisterMessage(GroupAttribute)
+
+GroupMembership = _reflection.GeneratedProtocolMessageType('GroupMembership', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPMEMBERSHIP,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.GroupMembership)
+  })
+_sym_db.RegisterMessage(GroupMembership)
+
+GroupToGroupMembership = _reflection.GeneratedProtocolMessageType('GroupToGroupMembership', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPTOGROUPMEMBERSHIP,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.GroupToGroupMembership)
+  })
+_sym_db.RegisterMessage(GroupToGroupMembership)
+
+Status = _reflection.GeneratedProtocolMessageType('Status', (_message.Message,), {
+  'DESCRIPTOR' : _STATUS,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.Status)
+  })
+_sym_db.RegisterMessage(Status)
+
+UserGroupMembershipTypeRequest = _reflection.GeneratedProtocolMessageType('UserGroupMembershipTypeRequest', (_message.Message,), {
+  'DESCRIPTOR' : _USERGROUPMEMBERSHIPTYPEREQUEST,
+  '__module__' : 'UserProfileService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.profile.service.UserGroupMembershipTypeRequest)
+  })
+_sym_db.RegisterMessage(UserGroupMembershipTypeRequest)
+
+
+DESCRIPTOR._options = None
+
+_USERPROFILESERVICE = _descriptor.ServiceDescriptor(
+  name='UserProfileService',
+  full_name='org.apache.custos.user.profile.service.UserProfileService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=2685,
+  serialized_end=5994,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='createUserProfile',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.createUserProfile',
+    index=0,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=_USERPROFILE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateUserProfile',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.updateUserProfile',
+    index=1,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=_USERPROFILE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUserProfile',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.getUserProfile',
+    index=2,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=_USERPROFILE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteUserProfile',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.deleteUserProfile',
+    index=3,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=_USERPROFILE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllUserProfilesInTenant',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.getAllUserProfilesInTenant',
+    index=4,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=_GETALLUSERPROFILESRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='findUserProfilesByAttributes',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.findUserProfilesByAttributes',
+    index=5,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=_GETALLUSERPROFILESRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createGroup',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.createGroup',
+    index=6,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUP,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateGroup',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.updateGroup',
+    index=7,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUP,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteGroup',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.deleteGroup',
+    index=8,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUP,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getGroup',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.getGroup',
+    index=9,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUP,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllGroups',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.getAllGroups',
+    index=10,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GETALLGROUPSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUserProfileAuditTrails',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.getUserProfileAuditTrails',
+    index=11,
+    containing_service=None,
+    input_type=_GETUPDATEAUDITTRAILREQUEST,
+    output_type=_GETUPDATEAUDITTRAILRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addUserToGroup',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.addUserToGroup',
+    index=12,
+    containing_service=None,
+    input_type=_GROUPMEMBERSHIP,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeUserFromGroup',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.removeUserFromGroup',
+    index=13,
+    containing_service=None,
+    input_type=_GROUPMEMBERSHIP,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addChildGroupToParentGroup',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.addChildGroupToParentGroup',
+    index=14,
+    containing_service=None,
+    input_type=_GROUPTOGROUPMEMBERSHIP,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeChildGroupFromParentGroup',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.removeChildGroupFromParentGroup',
+    index=15,
+    containing_service=None,
+    input_type=_GROUPTOGROUPMEMBERSHIP,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllGroupsOfUser',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.getAllGroupsOfUser',
+    index=16,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=_GETALLGROUPSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllParentGroupsOfGroup',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.getAllParentGroupsOfGroup',
+    index=17,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GETALLGROUPSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addUserGroupMembershipType',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.addUserGroupMembershipType',
+    index=18,
+    containing_service=None,
+    input_type=_USERGROUPMEMBERSHIPTYPEREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeUserGroupMembershipType',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.removeUserGroupMembershipType',
+    index=19,
+    containing_service=None,
+    input_type=_USERGROUPMEMBERSHIPTYPEREQUEST,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllChildUsers',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.getAllChildUsers',
+    index=20,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GETALLUSERPROFILESRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllChildGroups',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.getAllChildGroups',
+    index=21,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GETALLGROUPSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='changeUserMembershipType',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.changeUserMembershipType',
+    index=22,
+    containing_service=None,
+    input_type=_GROUPMEMBERSHIP,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='hasAccess',
+    full_name='org.apache.custos.user.profile.service.UserProfileService.hasAccess',
+    index=23,
+    containing_service=None,
+    input_type=_GROUPMEMBERSHIP,
+    output_type=_STATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_USERPROFILESERVICE)
+
+DESCRIPTOR.services_by_name['UserProfileService'] = _USERPROFILESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/core/UserProfileService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/core/UserProfileService_pb2_grpc.py
new file mode 100644
index 0000000..61e0a29
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/core/UserProfileService_pb2_grpc.py
@@ -0,0 +1,825 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import UserProfileService_pb2 as UserProfileService__pb2
+
+
+class UserProfileServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.createUserProfile = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/createUserProfile',
+                request_serializer=UserProfileService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.UserProfile.FromString,
+                )
+        self.updateUserProfile = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/updateUserProfile',
+                request_serializer=UserProfileService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.UserProfile.FromString,
+                )
+        self.getUserProfile = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/getUserProfile',
+                request_serializer=UserProfileService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.UserProfile.FromString,
+                )
+        self.deleteUserProfile = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/deleteUserProfile',
+                request_serializer=UserProfileService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.UserProfile.FromString,
+                )
+        self.getAllUserProfilesInTenant = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/getAllUserProfilesInTenant',
+                request_serializer=UserProfileService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+                )
+        self.findUserProfilesByAttributes = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/findUserProfilesByAttributes',
+                request_serializer=UserProfileService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+                )
+        self.createGroup = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/createGroup',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Group.FromString,
+                )
+        self.updateGroup = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/updateGroup',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Group.FromString,
+                )
+        self.deleteGroup = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/deleteGroup',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Group.FromString,
+                )
+        self.getGroup = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/getGroup',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Group.FromString,
+                )
+        self.getAllGroups = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/getAllGroups',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllGroupsResponse.FromString,
+                )
+        self.getUserProfileAuditTrails = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/getUserProfileAuditTrails',
+                request_serializer=UserProfileService__pb2.GetUpdateAuditTrailRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetUpdateAuditTrailResponse.FromString,
+                )
+        self.addUserToGroup = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/addUserToGroup',
+                request_serializer=UserProfileService__pb2.GroupMembership.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Status.FromString,
+                )
+        self.removeUserFromGroup = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/removeUserFromGroup',
+                request_serializer=UserProfileService__pb2.GroupMembership.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Status.FromString,
+                )
+        self.addChildGroupToParentGroup = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/addChildGroupToParentGroup',
+                request_serializer=UserProfileService__pb2.GroupToGroupMembership.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Status.FromString,
+                )
+        self.removeChildGroupFromParentGroup = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/removeChildGroupFromParentGroup',
+                request_serializer=UserProfileService__pb2.GroupToGroupMembership.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Status.FromString,
+                )
+        self.getAllGroupsOfUser = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/getAllGroupsOfUser',
+                request_serializer=UserProfileService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllGroupsResponse.FromString,
+                )
+        self.getAllParentGroupsOfGroup = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/getAllParentGroupsOfGroup',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllGroupsResponse.FromString,
+                )
+        self.addUserGroupMembershipType = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/addUserGroupMembershipType',
+                request_serializer=UserProfileService__pb2.UserGroupMembershipTypeRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Status.FromString,
+                )
+        self.removeUserGroupMembershipType = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/removeUserGroupMembershipType',
+                request_serializer=UserProfileService__pb2.UserGroupMembershipTypeRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Status.FromString,
+                )
+        self.getAllChildUsers = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/getAllChildUsers',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+                )
+        self.getAllChildGroups = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/getAllChildGroups',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllGroupsResponse.FromString,
+                )
+        self.changeUserMembershipType = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/changeUserMembershipType',
+                request_serializer=UserProfileService__pb2.GroupMembership.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Status.FromString,
+                )
+        self.hasAccess = channel.unary_unary(
+                '/org.apache.custos.user.profile.service.UserProfileService/hasAccess',
+                request_serializer=UserProfileService__pb2.GroupMembership.SerializeToString,
+                response_deserializer=UserProfileService__pb2.Status.FromString,
+                )
+
+
+class UserProfileServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def createUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllUserProfilesInTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def findUserProfilesByAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def createGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getUserProfileAuditTrails(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addUserToGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeUserFromGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addChildGroupToParentGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeChildGroupFromParentGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllGroupsOfUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllParentGroupsOfGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addUserGroupMembershipType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeUserGroupMembershipType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllChildUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllChildGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def changeUserMembershipType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def hasAccess(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_UserProfileServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'createUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.createUserProfile,
+                    request_deserializer=UserProfileService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.UserProfile.SerializeToString,
+            ),
+            'updateUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateUserProfile,
+                    request_deserializer=UserProfileService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.UserProfile.SerializeToString,
+            ),
+            'getUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.getUserProfile,
+                    request_deserializer=UserProfileService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.UserProfile.SerializeToString,
+            ),
+            'deleteUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteUserProfile,
+                    request_deserializer=UserProfileService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.UserProfile.SerializeToString,
+            ),
+            'getAllUserProfilesInTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllUserProfilesInTenant,
+                    request_deserializer=UserProfileService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllUserProfilesResponse.SerializeToString,
+            ),
+            'findUserProfilesByAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.findUserProfilesByAttributes,
+                    request_deserializer=UserProfileService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllUserProfilesResponse.SerializeToString,
+            ),
+            'createGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.createGroup,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.Group.SerializeToString,
+            ),
+            'updateGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateGroup,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.Group.SerializeToString,
+            ),
+            'deleteGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteGroup,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.Group.SerializeToString,
+            ),
+            'getGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.getGroup,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.Group.SerializeToString,
+            ),
+            'getAllGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllGroups,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllGroupsResponse.SerializeToString,
+            ),
+            'getUserProfileAuditTrails': grpc.unary_unary_rpc_method_handler(
+                    servicer.getUserProfileAuditTrails,
+                    request_deserializer=UserProfileService__pb2.GetUpdateAuditTrailRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetUpdateAuditTrailResponse.SerializeToString,
+            ),
+            'addUserToGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.addUserToGroup,
+                    request_deserializer=UserProfileService__pb2.GroupMembership.FromString,
+                    response_serializer=UserProfileService__pb2.Status.SerializeToString,
+            ),
+            'removeUserFromGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeUserFromGroup,
+                    request_deserializer=UserProfileService__pb2.GroupMembership.FromString,
+                    response_serializer=UserProfileService__pb2.Status.SerializeToString,
+            ),
+            'addChildGroupToParentGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.addChildGroupToParentGroup,
+                    request_deserializer=UserProfileService__pb2.GroupToGroupMembership.FromString,
+                    response_serializer=UserProfileService__pb2.Status.SerializeToString,
+            ),
+            'removeChildGroupFromParentGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeChildGroupFromParentGroup,
+                    request_deserializer=UserProfileService__pb2.GroupToGroupMembership.FromString,
+                    response_serializer=UserProfileService__pb2.Status.SerializeToString,
+            ),
+            'getAllGroupsOfUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllGroupsOfUser,
+                    request_deserializer=UserProfileService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllGroupsResponse.SerializeToString,
+            ),
+            'getAllParentGroupsOfGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllParentGroupsOfGroup,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllGroupsResponse.SerializeToString,
+            ),
+            'addUserGroupMembershipType': grpc.unary_unary_rpc_method_handler(
+                    servicer.addUserGroupMembershipType,
+                    request_deserializer=UserProfileService__pb2.UserGroupMembershipTypeRequest.FromString,
+                    response_serializer=UserProfileService__pb2.Status.SerializeToString,
+            ),
+            'removeUserGroupMembershipType': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeUserGroupMembershipType,
+                    request_deserializer=UserProfileService__pb2.UserGroupMembershipTypeRequest.FromString,
+                    response_serializer=UserProfileService__pb2.Status.SerializeToString,
+            ),
+            'getAllChildUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllChildUsers,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllUserProfilesResponse.SerializeToString,
+            ),
+            'getAllChildGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllChildGroups,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllGroupsResponse.SerializeToString,
+            ),
+            'changeUserMembershipType': grpc.unary_unary_rpc_method_handler(
+                    servicer.changeUserMembershipType,
+                    request_deserializer=UserProfileService__pb2.GroupMembership.FromString,
+                    response_serializer=UserProfileService__pb2.Status.SerializeToString,
+            ),
+            'hasAccess': grpc.unary_unary_rpc_method_handler(
+                    servicer.hasAccess,
+                    request_deserializer=UserProfileService__pb2.GroupMembership.FromString,
+                    response_serializer=UserProfileService__pb2.Status.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'org.apache.custos.user.profile.service.UserProfileService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class UserProfileService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def createUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/createUserProfile',
+            UserProfileService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.UserProfile.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/updateUserProfile',
+            UserProfileService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.UserProfile.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/getUserProfile',
+            UserProfileService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.UserProfile.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/deleteUserProfile',
+            UserProfileService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.UserProfile.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllUserProfilesInTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/getAllUserProfilesInTenant',
+            UserProfileService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def findUserProfilesByAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/findUserProfilesByAttributes',
+            UserProfileService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def createGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/createGroup',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.Group.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/updateGroup',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.Group.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/deleteGroup',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.Group.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/getGroup',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.Group.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/getAllGroups',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.GetAllGroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getUserProfileAuditTrails(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/getUserProfileAuditTrails',
+            UserProfileService__pb2.GetUpdateAuditTrailRequest.SerializeToString,
+            UserProfileService__pb2.GetUpdateAuditTrailResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addUserToGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/addUserToGroup',
+            UserProfileService__pb2.GroupMembership.SerializeToString,
+            UserProfileService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeUserFromGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/removeUserFromGroup',
+            UserProfileService__pb2.GroupMembership.SerializeToString,
+            UserProfileService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addChildGroupToParentGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/addChildGroupToParentGroup',
+            UserProfileService__pb2.GroupToGroupMembership.SerializeToString,
+            UserProfileService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeChildGroupFromParentGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/removeChildGroupFromParentGroup',
+            UserProfileService__pb2.GroupToGroupMembership.SerializeToString,
+            UserProfileService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllGroupsOfUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/getAllGroupsOfUser',
+            UserProfileService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.GetAllGroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllParentGroupsOfGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/getAllParentGroupsOfGroup',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.GetAllGroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addUserGroupMembershipType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/addUserGroupMembershipType',
+            UserProfileService__pb2.UserGroupMembershipTypeRequest.SerializeToString,
+            UserProfileService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeUserGroupMembershipType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/removeUserGroupMembershipType',
+            UserProfileService__pb2.UserGroupMembershipTypeRequest.SerializeToString,
+            UserProfileService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllChildUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/getAllChildUsers',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllChildGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/getAllChildGroups',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.GetAllGroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def changeUserMembershipType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/changeUserMembershipType',
+            UserProfileService__pb2.GroupMembership.SerializeToString,
+            UserProfileService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def hasAccess(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.profile.service.UserProfileService/hasAccess',
+            UserProfileService__pb2.GroupMembership.SerializeToString,
+            UserProfileService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/custos/server/core/__init__.py
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/custos/server/core/__init__.py
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/AgentManagementService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/AgentManagementService_pb2.py
new file mode 100644
index 0000000..34b2527
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/AgentManagementService_pb2.py
@@ -0,0 +1,278 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: AgentManagementService.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
+from google.rpc import error_details_pb2 as google_dot_rpc_dot_error__details__pb2
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+import custos.server.core.IamAdminService_pb2 as IamAdminService__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='AgentManagementService.proto',
+  package='org.apache.custos.agent.management.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n\x1c\x41gentManagementService.proto\x12*org.apache.custos.agent.management.service\x1a\x1cgoogle/api/annotations.proto\x1a\x1egoogle/rpc/error_details.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x15IamAdminService.proto\"\x81\x01\n\x12\x41gentSearchRequest\x12\x10\n\x08tenantId\x18\x02 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\x11\n\tclientSec\x18\x05 \x01(\t\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\x12\n\n\x02id\x18\x07 \x01(\t\"7\n\x19\x41gentRegistrationResponse\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t2\xdd\x10\n\x16\x41gentManagementService\x12\x9b\x01\n\x0c\x65nableAgents\x12\x32.org.apache.custos.iam.service.AgentClientMetadata\x1a..org.apache.custos.iam.service.OperationStatus\"\'\x82\xd3\xe4\x93\x02!\"\x1f/agent-management/v1.0.0/enable\x12\xb0\x01\n\x14\x63onfigureAgentClient\x12\x32.org.apache.custos.iam.service.AgentClientMetadata\x1a..org.apache.custos.iam.service.OperationStatus\"4\x82\xd3\xe4\x93\x02.\",/agent-management/v1.0.0/token/configuration\x12\xc1\x01\n\x16registerAndEnableAgent\x12\x32.org.apache.custos.iam.service.RegisterUserRequest\x1a\x45.org.apache.custos.agent.management.service.AgentRegistrationResponse\",\x82\xd3\xe4\x93\x02&\"\x1e/agent-management/v1.0.0/agent:\x04user\x12\x9d\x01\n\x08getAgent\x12>.org.apache.custos.agent.management.service.AgentSearchRequest\x1a$.org.apache.custos.iam.service.Agent\"+\x82\xd3\xe4\x93\x02%\x12#/agent-management/v1.0.0/agent/{id}\x12\xaa\x01\n\x0b\x64\x65leteAgent\x12>.org.apache.custos.agent.management.service.AgentSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\"+\x82\xd3\xe4\x93\x02%*#/agent-management/v1.0.0/agent/{id}\x12\xb8\x01\n\x0c\x64isableAgent\x12>.org.apache.custos.agent.management.service.AgentSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\"8\x82\xd3\xe4\x93\x02\x32\"0/agent-management/v1.0.0/agent/deactivation/{id}\x12\xb5\x01\n\x0b\x65nableAgent\x12>.org.apache.custos.agent.management.service.AgentSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\"6\x82\xd3\xe4\x93\x02\x30\"./agent-management/v1.0.0/agent/activation/{id}\x12\xb0\x01\n\x12\x61\x64\x64\x41gentAttributes\x12\x37.org.apache.custos.iam.service.AddUserAttributesRequest\x1a..org.apache.custos.iam.service.OperationStatus\"1\x82\xd3\xe4\x93\x02+\")/agent-management/v1.0.0/agent/attributes\x12\xb5\x01\n\x15\x64\x65leteAgentAttributes\x12\x39.org.apache.custos.iam.service.DeleteUserAttributeRequest\x1a..org.apache.custos.iam.service.OperationStatus\"1\x82\xd3\xe4\x93\x02+*)/agent-management/v1.0.0/agent/attributes\x12\xa3\x01\n\x0f\x61\x64\x64RolesToAgent\x12\x32.org.apache.custos.iam.service.AddUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\",\x82\xd3\xe4\x93\x02&\"$/agent-management/v1.0.0/agent/roles\x12\xab\x01\n\x14\x64\x65leteRolesFromAgent\x12\x35.org.apache.custos.iam.service.DeleteUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\",\x82\xd3\xe4\x93\x02&*$/agent-management/v1.0.0/agent/roles\x12\xae\x01\n\x11\x61\x64\x64ProtocolMapper\x12\x37.org.apache.custos.iam.service.AddProtocolMapperRequest\x1a..org.apache.custos.iam.service.OperationStatus\"0\x82\xd3\xe4\x93\x02*\"(/agent-management/v1.0.0/protocol/mapperB\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,google_dot_rpc_dot_error__details__pb2.DESCRIPTOR,google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,IamAdminService__pb2.DESCRIPTOR,])
+
+
+
+
+_AGENTSEARCHREQUEST = _descriptor.Descriptor(
+  name='AgentSearchRequest',
+  full_name='org.apache.custos.agent.management.service.AgentSearchRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.agent.management.service.AgentSearchRequest.tenantId', index=0,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.agent.management.service.AgentSearchRequest.accessToken', index=1,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.agent.management.service.AgentSearchRequest.clientId', index=2,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.agent.management.service.AgentSearchRequest.clientSec', index=3,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.agent.management.service.AgentSearchRequest.performedBy', index=4,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.agent.management.service.AgentSearchRequest.id', index=5,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=191,
+  serialized_end=320,
+)
+
+
+_AGENTREGISTRATIONRESPONSE = _descriptor.Descriptor(
+  name='AgentRegistrationResponse',
+  full_name='org.apache.custos.agent.management.service.AgentRegistrationResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.agent.management.service.AgentRegistrationResponse.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='secret', full_name='org.apache.custos.agent.management.service.AgentRegistrationResponse.secret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=322,
+  serialized_end=377,
+)
+
+DESCRIPTOR.message_types_by_name['AgentSearchRequest'] = _AGENTSEARCHREQUEST
+DESCRIPTOR.message_types_by_name['AgentRegistrationResponse'] = _AGENTREGISTRATIONRESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+AgentSearchRequest = _reflection.GeneratedProtocolMessageType('AgentSearchRequest', (_message.Message,), {
+  'DESCRIPTOR' : _AGENTSEARCHREQUEST,
+  '__module__' : 'AgentManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.agent.management.service.AgentSearchRequest)
+  })
+_sym_db.RegisterMessage(AgentSearchRequest)
+
+AgentRegistrationResponse = _reflection.GeneratedProtocolMessageType('AgentRegistrationResponse', (_message.Message,), {
+  'DESCRIPTOR' : _AGENTREGISTRATIONRESPONSE,
+  '__module__' : 'AgentManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.agent.management.service.AgentRegistrationResponse)
+  })
+_sym_db.RegisterMessage(AgentRegistrationResponse)
+
+
+DESCRIPTOR._options = None
+
+_AGENTMANAGEMENTSERVICE = _descriptor.ServiceDescriptor(
+  name='AgentManagementService',
+  full_name='org.apache.custos.agent.management.service.AgentManagementService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=380,
+  serialized_end=2521,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='enableAgents',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.enableAgents',
+    index=0,
+    containing_service=None,
+    input_type=IamAdminService__pb2._AGENTCLIENTMETADATA,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002!\"\037/agent-management/v1.0.0/enable',
+  ),
+  _descriptor.MethodDescriptor(
+    name='configureAgentClient',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.configureAgentClient',
+    index=1,
+    containing_service=None,
+    input_type=IamAdminService__pb2._AGENTCLIENTMETADATA,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002.\",/agent-management/v1.0.0/token/configuration',
+  ),
+  _descriptor.MethodDescriptor(
+    name='registerAndEnableAgent',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.registerAndEnableAgent',
+    index=2,
+    containing_service=None,
+    input_type=IamAdminService__pb2._REGISTERUSERREQUEST,
+    output_type=_AGENTREGISTRATIONRESPONSE,
+    serialized_options=b'\202\323\344\223\002&\"\036/agent-management/v1.0.0/agent:\004user',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAgent',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.getAgent',
+    index=3,
+    containing_service=None,
+    input_type=_AGENTSEARCHREQUEST,
+    output_type=IamAdminService__pb2._AGENT,
+    serialized_options=b'\202\323\344\223\002%\022#/agent-management/v1.0.0/agent/{id}',
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgent',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.deleteAgent',
+    index=4,
+    containing_service=None,
+    input_type=_AGENTSEARCHREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002%*#/agent-management/v1.0.0/agent/{id}',
+  ),
+  _descriptor.MethodDescriptor(
+    name='disableAgent',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.disableAgent',
+    index=5,
+    containing_service=None,
+    input_type=_AGENTSEARCHREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\0022\"0/agent-management/v1.0.0/agent/deactivation/{id}',
+  ),
+  _descriptor.MethodDescriptor(
+    name='enableAgent',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.enableAgent',
+    index=6,
+    containing_service=None,
+    input_type=_AGENTSEARCHREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\0020\"./agent-management/v1.0.0/agent/activation/{id}',
+  ),
+  _descriptor.MethodDescriptor(
+    name='addAgentAttributes',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.addAgentAttributes',
+    index=7,
+    containing_service=None,
+    input_type=IamAdminService__pb2._ADDUSERATTRIBUTESREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002+\")/agent-management/v1.0.0/agent/attributes',
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgentAttributes',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.deleteAgentAttributes',
+    index=8,
+    containing_service=None,
+    input_type=IamAdminService__pb2._DELETEUSERATTRIBUTEREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002+*)/agent-management/v1.0.0/agent/attributes',
+  ),
+  _descriptor.MethodDescriptor(
+    name='addRolesToAgent',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.addRolesToAgent',
+    index=9,
+    containing_service=None,
+    input_type=IamAdminService__pb2._ADDUSERROLESREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002&\"$/agent-management/v1.0.0/agent/roles',
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteRolesFromAgent',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.deleteRolesFromAgent',
+    index=10,
+    containing_service=None,
+    input_type=IamAdminService__pb2._DELETEUSERROLESREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002&*$/agent-management/v1.0.0/agent/roles',
+  ),
+  _descriptor.MethodDescriptor(
+    name='addProtocolMapper',
+    full_name='org.apache.custos.agent.management.service.AgentManagementService.addProtocolMapper',
+    index=11,
+    containing_service=None,
+    input_type=IamAdminService__pb2._ADDPROTOCOLMAPPERREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002*\"(/agent-management/v1.0.0/protocol/mapper',
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_AGENTMANAGEMENTSERVICE)
+
+DESCRIPTOR.services_by_name['AgentManagementService'] = _AGENTMANAGEMENTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/AgentManagementService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/AgentManagementService_pb2_grpc.py
new file mode 100644
index 0000000..bd64d48
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/AgentManagementService_pb2_grpc.py
@@ -0,0 +1,234 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import custos.server.integration.AgentManagementService_pb2 as AgentManagementService__pb2
+import custos.server.core.IamAdminService_pb2 as IamAdminService__pb2
+
+
+class AgentManagementServiceStub(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.enableAgents = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/enableAgents',
+        request_serializer=IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.configureAgentClient = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/configureAgentClient',
+        request_serializer=IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.registerAndEnableAgent = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/registerAndEnableAgent',
+        request_serializer=IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+        response_deserializer=AgentManagementService__pb2.AgentRegistrationResponse.FromString,
+        )
+    self.getAgent = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/getAgent',
+        request_serializer=AgentManagementService__pb2.AgentSearchRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.Agent.FromString,
+        )
+    self.deleteAgent = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/deleteAgent',
+        request_serializer=AgentManagementService__pb2.AgentSearchRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.disableAgent = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/disableAgent',
+        request_serializer=AgentManagementService__pb2.AgentSearchRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.enableAgent = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/enableAgent',
+        request_serializer=AgentManagementService__pb2.AgentSearchRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.addAgentAttributes = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/addAgentAttributes',
+        request_serializer=IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.deleteAgentAttributes = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/deleteAgentAttributes',
+        request_serializer=IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.addRolesToAgent = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/addRolesToAgent',
+        request_serializer=IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.deleteRolesFromAgent = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/deleteRolesFromAgent',
+        request_serializer=IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.addProtocolMapper = channel.unary_unary(
+        '/org.apache.custos.agent.management.service.AgentManagementService/addProtocolMapper',
+        request_serializer=IamAdminService__pb2.AddProtocolMapperRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+
+
+class AgentManagementServiceServicer(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def enableAgents(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def configureAgentClient(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def registerAndEnableAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def disableAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def enableAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def addAgentAttributes(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteAgentAttributes(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def addRolesToAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteRolesFromAgent(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def addProtocolMapper(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_AgentManagementServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'enableAgents': grpc.unary_unary_rpc_method_handler(
+          servicer.enableAgents,
+          request_deserializer=IamAdminService__pb2.AgentClientMetadata.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'configureAgentClient': grpc.unary_unary_rpc_method_handler(
+          servicer.configureAgentClient,
+          request_deserializer=IamAdminService__pb2.AgentClientMetadata.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'registerAndEnableAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.registerAndEnableAgent,
+          request_deserializer=IamAdminService__pb2.RegisterUserRequest.FromString,
+          response_serializer=AgentManagementService__pb2.AgentRegistrationResponse.SerializeToString,
+      ),
+      'getAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.getAgent,
+          request_deserializer=AgentManagementService__pb2.AgentSearchRequest.FromString,
+          response_serializer=IamAdminService__pb2.Agent.SerializeToString,
+      ),
+      'deleteAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteAgent,
+          request_deserializer=AgentManagementService__pb2.AgentSearchRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'disableAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.disableAgent,
+          request_deserializer=AgentManagementService__pb2.AgentSearchRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'enableAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.enableAgent,
+          request_deserializer=AgentManagementService__pb2.AgentSearchRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'addAgentAttributes': grpc.unary_unary_rpc_method_handler(
+          servicer.addAgentAttributes,
+          request_deserializer=IamAdminService__pb2.AddUserAttributesRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'deleteAgentAttributes': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteAgentAttributes,
+          request_deserializer=IamAdminService__pb2.DeleteUserAttributeRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'addRolesToAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.addRolesToAgent,
+          request_deserializer=IamAdminService__pb2.AddUserRolesRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'deleteRolesFromAgent': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteRolesFromAgent,
+          request_deserializer=IamAdminService__pb2.DeleteUserRolesRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'addProtocolMapper': grpc.unary_unary_rpc_method_handler(
+          servicer.addProtocolMapper,
+          request_deserializer=IamAdminService__pb2.AddProtocolMapperRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.custos.agent.management.service.AgentManagementService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/GroupManagementService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/GroupManagementService_pb2.py
new file mode 100644
index 0000000..f12516c
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/GroupManagementService_pb2.py
@@ -0,0 +1,201 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: GroupManagementService.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
+import custos.server.core.UserProfileService_pb2 as UserProfileService__pb2
+import custos.server.core.IamAdminService_pb2 as IamAdminService__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='GroupManagementService.proto',
+  package='org.apache.custos.group.management.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x1cGroupManagementService.proto\x12*org.apache.custos.group.management.service\x1a\x1cgoogle/api/annotations.proto\x1a\x18UserProfileService.proto\x1a\x15IamAdminService.proto2\x95\x15\n\x16GroupManagementService\x12\x94\x01\n\x0c\x63reateGroups\x12,.org.apache.custos.iam.service.GroupsRequest\x1a-.org.apache.custos.iam.service.GroupsResponse\"\'\x82\xd3\xe4\x93\x02!\"\x1f/group-management/v1.0.0/groups\x12\x9b\x01\n\x0bupdateGroup\x12+.org.apache.custos.iam.service.GroupRequest\x1a\x32.org.apache.custos.iam.service.GroupRepresentation\"+\x82\xd3\xe4\x93\x02%\x1a#/group-management/v1.0.0/group/{id}\x12\x97\x01\n\x0b\x64\x65leteGroup\x12+.org.apache.custos.iam.service.GroupRequest\x1a..org.apache.custos.iam.service.OperationStatus\"+\x82\xd3\xe4\x93\x02%*#/group-management/v1.0.0/group/{id}\x12\x94\x01\n\tfindGroup\x12+.org.apache.custos.iam.service.GroupRequest\x1a\x32.org.apache.custos.iam.service.GroupRepresentation\"&\x82\xd3\xe4\x93\x02 \x12\x1e/group-management/v1.0.0/group\x12\x93\x01\n\x0cgetAllGroups\x12+.org.apache.custos.iam.service.GroupRequest\x1a-.org.apache.custos.iam.service.GroupsResponse\"\'\x82\xd3\xe4\x93\x02!\x12\x1f/group-management/v1.0.0/groups\x12\xb0\x01\n\x0e\x61\x64\x64UserToGroup\x12\x36.org.apache.custos.iam.service.UserGroupMappingRequest\x1a..org.apache.custos.iam.service.OperationStatus\"6\x82\xd3\xe4\x93\x02\x30\"./group-management/v1.0.0/user/group/membership\x12\xb5\x01\n\x13removeUserFromGroup\x12\x36.org.apache.custos.iam.service.UserGroupMappingRequest\x1a..org.apache.custos.iam.service.OperationStatus\"6\x82\xd3\xe4\x93\x02\x30*./group-management/v1.0.0/user/group/membership\x12\xbf\x01\n\x1a\x61\x64\x64\x43hildGroupToParentGroup\x12>.org.apache.custos.user.profile.service.GroupToGroupMembership\x1a..org.apache.custos.iam.service.OperationStatus\"1\x82\xd3\xe4\x93\x02+\")/group-management/v1.0.0/group/membership\x12\xc4\x01\n\x1fremoveChildGroupFromParentGroup\x12>.org.apache.custos.user.profile.service.GroupToGroupMembership\x1a..org.apache.custos.iam.service.OperationStatus\"1\x82\xd3\xe4\x93\x02+*)/group-management/v1.0.0/group/membership\x12\xc7\x01\n\x12getAllGroupsOfUser\x12:.org.apache.custos.user.profile.service.UserProfileRequest\x1a<.org.apache.custos.user.profile.service.GetAllGroupsResponse\"7\x82\xd3\xe4\x93\x02\x31\x12//group-management/v1.0.0/user/group/memberships\x12\xc4\x01\n\x19getAllParentGroupsOfGroup\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a<.org.apache.custos.user.profile.service.GetAllGroupsResponse\"3\x82\xd3\xe4\x93\x02-\x12+/group-management/v1.0.0/groups/memberships\x12\xcb\x01\n\x10getAllChildUsers\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a\x42.org.apache.custos.user.profile.service.GetAllUserProfilesResponse\"=\x82\xd3\xe4\x93\x02\x37\x12\x35/group-management/v1.0.0/user/group/memberships/child\x12\xc2\x01\n\x11getAllChildGroups\x12\x34.org.apache.custos.user.profile.service.GroupRequest\x1a<.org.apache.custos.user.profile.service.GetAllGroupsResponse\"9\x82\xd3\xe4\x93\x02\x33\x12\x31/group-management/v1.0.0/groups/memberships/child\x12\xbb\x01\n\x18\x63hangeUserMembershipType\x12\x37.org.apache.custos.user.profile.service.GroupMembership\x1a..org.apache.custos.iam.service.OperationStatus\"6\x82\xd3\xe4\x93\x02\x30\x1a./group-management/v1.0.0/user/group/membership\x12\xa8\x01\n\thasAccess\x12\x37.org.apache.custos.user.profile.service.GroupMembership\x1a..org.apache.custos.iam.service.OperationStatus\"2\x82\xd3\xe4\x93\x02,\x12*/group-management/v1.0.0/user/group/accessB\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,UserProfileService__pb2.DESCRIPTOR,IamAdminService__pb2.DESCRIPTOR,])
+
+
+
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+DESCRIPTOR._options = None
+
+_GROUPMANAGEMENTSERVICE = _descriptor.ServiceDescriptor(
+  name='GroupManagementService',
+  full_name='org.apache.custos.group.management.service.GroupManagementService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=156,
+  serialized_end=2865,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='createGroups',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.createGroups',
+    index=0,
+    containing_service=None,
+    input_type=IamAdminService__pb2._GROUPSREQUEST,
+    output_type=IamAdminService__pb2._GROUPSRESPONSE,
+    serialized_options=b'\202\323\344\223\002!\"\037/group-management/v1.0.0/groups',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateGroup',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.updateGroup',
+    index=1,
+    containing_service=None,
+    input_type=IamAdminService__pb2._GROUPREQUEST,
+    output_type=IamAdminService__pb2._GROUPREPRESENTATION,
+    serialized_options=b'\202\323\344\223\002%\032#/group-management/v1.0.0/group/{id}',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteGroup',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.deleteGroup',
+    index=2,
+    containing_service=None,
+    input_type=IamAdminService__pb2._GROUPREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002%*#/group-management/v1.0.0/group/{id}',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='findGroup',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.findGroup',
+    index=3,
+    containing_service=None,
+    input_type=IamAdminService__pb2._GROUPREQUEST,
+    output_type=IamAdminService__pb2._GROUPREPRESENTATION,
+    serialized_options=b'\202\323\344\223\002 \022\036/group-management/v1.0.0/group',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllGroups',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.getAllGroups',
+    index=4,
+    containing_service=None,
+    input_type=IamAdminService__pb2._GROUPREQUEST,
+    output_type=IamAdminService__pb2._GROUPSRESPONSE,
+    serialized_options=b'\202\323\344\223\002!\022\037/group-management/v1.0.0/groups',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addUserToGroup',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.addUserToGroup',
+    index=5,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERGROUPMAPPINGREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\0020\"./group-management/v1.0.0/user/group/membership',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeUserFromGroup',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.removeUserFromGroup',
+    index=6,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERGROUPMAPPINGREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\0020*./group-management/v1.0.0/user/group/membership',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addChildGroupToParentGroup',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.addChildGroupToParentGroup',
+    index=7,
+    containing_service=None,
+    input_type=UserProfileService__pb2._GROUPTOGROUPMEMBERSHIP,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002+\")/group-management/v1.0.0/group/membership',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeChildGroupFromParentGroup',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.removeChildGroupFromParentGroup',
+    index=8,
+    containing_service=None,
+    input_type=UserProfileService__pb2._GROUPTOGROUPMEMBERSHIP,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002+*)/group-management/v1.0.0/group/membership',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllGroupsOfUser',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.getAllGroupsOfUser',
+    index=9,
+    containing_service=None,
+    input_type=UserProfileService__pb2._USERPROFILEREQUEST,
+    output_type=UserProfileService__pb2._GETALLGROUPSRESPONSE,
+    serialized_options=b'\202\323\344\223\0021\022//group-management/v1.0.0/user/group/memberships',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllParentGroupsOfGroup',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.getAllParentGroupsOfGroup',
+    index=10,
+    containing_service=None,
+    input_type=UserProfileService__pb2._GROUPREQUEST,
+    output_type=UserProfileService__pb2._GETALLGROUPSRESPONSE,
+    serialized_options=b'\202\323\344\223\002-\022+/group-management/v1.0.0/groups/memberships',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllChildUsers',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.getAllChildUsers',
+    index=11,
+    containing_service=None,
+    input_type=UserProfileService__pb2._GROUPREQUEST,
+    output_type=UserProfileService__pb2._GETALLUSERPROFILESRESPONSE,
+    serialized_options=b'\202\323\344\223\0027\0225/group-management/v1.0.0/user/group/memberships/child',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllChildGroups',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.getAllChildGroups',
+    index=12,
+    containing_service=None,
+    input_type=UserProfileService__pb2._GROUPREQUEST,
+    output_type=UserProfileService__pb2._GETALLGROUPSRESPONSE,
+    serialized_options=b'\202\323\344\223\0023\0221/group-management/v1.0.0/groups/memberships/child',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='changeUserMembershipType',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.changeUserMembershipType',
+    index=13,
+    containing_service=None,
+    input_type=UserProfileService__pb2._GROUPMEMBERSHIP,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\0020\032./group-management/v1.0.0/user/group/membership',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='hasAccess',
+    full_name='org.apache.custos.group.management.service.GroupManagementService.hasAccess',
+    index=14,
+    containing_service=None,
+    input_type=UserProfileService__pb2._GROUPMEMBERSHIP,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002,\022*/group-management/v1.0.0/user/group/access',
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_GROUPMANAGEMENTSERVICE)
+
+DESCRIPTOR.services_by_name['GroupManagementService'] = _GROUPMANAGEMENTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/GroupManagementService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/GroupManagementService_pb2_grpc.py
new file mode 100644
index 0000000..975983f
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/GroupManagementService_pb2_grpc.py
@@ -0,0 +1,529 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import custos.server.core.IamAdminService_pb2 as IamAdminService__pb2
+import custos.server.core.UserProfileService_pb2 as UserProfileService__pb2
+
+
+class GroupManagementServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.createGroups = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/createGroups',
+                request_serializer=IamAdminService__pb2.GroupsRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupsResponse.FromString,
+                )
+        self.updateGroup = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/updateGroup',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupRepresentation.FromString,
+                )
+        self.deleteGroup = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/deleteGroup',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.findGroup = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/findGroup',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupRepresentation.FromString,
+                )
+        self.getAllGroups = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/getAllGroups',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupsResponse.FromString,
+                )
+        self.addUserToGroup = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/addUserToGroup',
+                request_serializer=IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.removeUserFromGroup = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/removeUserFromGroup',
+                request_serializer=IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.addChildGroupToParentGroup = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/addChildGroupToParentGroup',
+                request_serializer=UserProfileService__pb2.GroupToGroupMembership.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.removeChildGroupFromParentGroup = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/removeChildGroupFromParentGroup',
+                request_serializer=UserProfileService__pb2.GroupToGroupMembership.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getAllGroupsOfUser = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/getAllGroupsOfUser',
+                request_serializer=UserProfileService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllGroupsResponse.FromString,
+                )
+        self.getAllParentGroupsOfGroup = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/getAllParentGroupsOfGroup',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllGroupsResponse.FromString,
+                )
+        self.getAllChildUsers = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/getAllChildUsers',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+                )
+        self.getAllChildGroups = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/getAllChildGroups',
+                request_serializer=UserProfileService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllGroupsResponse.FromString,
+                )
+        self.changeUserMembershipType = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/changeUserMembershipType',
+                request_serializer=UserProfileService__pb2.GroupMembership.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.hasAccess = channel.unary_unary(
+                '/org.apache.custos.group.management.service.GroupManagementService/hasAccess',
+                request_serializer=UserProfileService__pb2.GroupMembership.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+
+
+class GroupManagementServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def createGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def findGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addUserToGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeUserFromGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addChildGroupToParentGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeChildGroupFromParentGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllGroupsOfUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllParentGroupsOfGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllChildUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllChildGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def changeUserMembershipType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def hasAccess(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_GroupManagementServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'createGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.createGroups,
+                    request_deserializer=IamAdminService__pb2.GroupsRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupsResponse.SerializeToString,
+            ),
+            'updateGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateGroup,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupRepresentation.SerializeToString,
+            ),
+            'deleteGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteGroup,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'findGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.findGroup,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupRepresentation.SerializeToString,
+            ),
+            'getAllGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllGroups,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupsResponse.SerializeToString,
+            ),
+            'addUserToGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.addUserToGroup,
+                    request_deserializer=IamAdminService__pb2.UserGroupMappingRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'removeUserFromGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeUserFromGroup,
+                    request_deserializer=IamAdminService__pb2.UserGroupMappingRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'addChildGroupToParentGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.addChildGroupToParentGroup,
+                    request_deserializer=UserProfileService__pb2.GroupToGroupMembership.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'removeChildGroupFromParentGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeChildGroupFromParentGroup,
+                    request_deserializer=UserProfileService__pb2.GroupToGroupMembership.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getAllGroupsOfUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllGroupsOfUser,
+                    request_deserializer=UserProfileService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllGroupsResponse.SerializeToString,
+            ),
+            'getAllParentGroupsOfGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllParentGroupsOfGroup,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllGroupsResponse.SerializeToString,
+            ),
+            'getAllChildUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllChildUsers,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllUserProfilesResponse.SerializeToString,
+            ),
+            'getAllChildGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllChildGroups,
+                    request_deserializer=UserProfileService__pb2.GroupRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllGroupsResponse.SerializeToString,
+            ),
+            'changeUserMembershipType': grpc.unary_unary_rpc_method_handler(
+                    servicer.changeUserMembershipType,
+                    request_deserializer=UserProfileService__pb2.GroupMembership.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'hasAccess': grpc.unary_unary_rpc_method_handler(
+                    servicer.hasAccess,
+                    request_deserializer=UserProfileService__pb2.GroupMembership.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'org.apache.custos.group.management.service.GroupManagementService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class GroupManagementService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def createGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/createGroups',
+            IamAdminService__pb2.GroupsRequest.SerializeToString,
+            IamAdminService__pb2.GroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/updateGroup',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.GroupRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/deleteGroup',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def findGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/findGroup',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.GroupRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/getAllGroups',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.GroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addUserToGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/addUserToGroup',
+            IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeUserFromGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/removeUserFromGroup',
+            IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addChildGroupToParentGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/addChildGroupToParentGroup',
+            UserProfileService__pb2.GroupToGroupMembership.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeChildGroupFromParentGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/removeChildGroupFromParentGroup',
+            UserProfileService__pb2.GroupToGroupMembership.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllGroupsOfUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/getAllGroupsOfUser',
+            UserProfileService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.GetAllGroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllParentGroupsOfGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/getAllParentGroupsOfGroup',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.GetAllGroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllChildUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/getAllChildUsers',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllChildGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/getAllChildGroups',
+            UserProfileService__pb2.GroupRequest.SerializeToString,
+            UserProfileService__pb2.GetAllGroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def changeUserMembershipType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/changeUserMembershipType',
+            UserProfileService__pb2.GroupMembership.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def hasAccess(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.group.management.service.GroupManagementService/hasAccess',
+            UserProfileService__pb2.GroupMembership.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/IdentityManagementService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/IdentityManagementService_pb2.py
new file mode 100644
index 0000000..900697f
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/IdentityManagementService_pb2.py
@@ -0,0 +1,452 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: IdentityManagementService.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
+import custos.server.core.IdentityService_pb2 as IdentityService__pb2
+from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
+from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
+import custos.server.core.CredentialStoreService_pb2 as CredentialStoreService__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='IdentityManagementService.proto',
+  package='org.apache.custos.identity.management.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n\x1fIdentityManagementService.proto\x12-org.apache.custos.identity.management.service\x1a\x1cgoogle/api/annotations.proto\x1a\x15IdentityService.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x19google/protobuf/any.proto\x1a\x1c\x43redentialStoreService.proto\"\x9e\x01\n\x14\x41uthorizationRequest\x12\x11\n\ttenant_id\x18\x01 \x01(\x03\x12\x11\n\tclient_id\x18\x02 \x01(\t\x12\x15\n\rclient_secret\x18\x03 \x01(\t\x12\x14\n\x0credirect_uri\x18\x04 \x01(\t\x12\x15\n\rresponse_type\x18\x05 \x01(\t\x12\r\n\x05scope\x18\x06 \x01(\t\x12\r\n\x05state\x18\x07 \x01(\t\")\n\x15\x41uthorizationResponse\x12\x10\n\x08loginURI\x18\x01 \x01(\t\"x\n\x15GetCredentialsRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12L\n\x0b\x63redentials\x18\x02 \x01(\x0b\x32\x37.org.apache.custos.credential.store.service.Credentials\"\xc5\x01\n\x14GetAgentTokenRequest\x12\x11\n\ttenant_id\x18\x01 \x01(\x03\x12\x17\n\x0f\x61gent_client_id\x18\x02 \x01(\t\x12\x1b\n\x13\x61gent_client_secret\x18\x03 \x01(\t\x12\x0f\n\x07\x61gentId\x18\x04 \x01(\t\x12\x15\n\ragentPassword\x18\x05 \x01(\t\x12\x11\n\tclient_id\x18\x06 \x01(\t\x12\x12\n\ngrant_type\x18\x07 \x01(\t\x12\x15\n\rrefresh_token\x18\x08 \x01(\t\"k\n\x11\x45ndSessionRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x43\n\x04\x62ody\x18\x02 \x01(\x0b\x32\x35.org.apache.custos.identity.service.EndSessionRequest2\xe2\x0f\n\x19IdentityManagementService\x12\xaa\x01\n\x0c\x61uthenticate\x12\x39.org.apache.custos.identity.service.AuthenticationRequest\x1a-.org.apache.custos.identity.service.AuthToken\"0\x82\xd3\xe4\x93\x02*\"(/identity-management/v1.0.0/authenticate\x12\xb5\x01\n\x0fisAuthenticated\x12-.org.apache.custos.identity.service.AuthToken\x1a:.org.apache.custos.identity.service.IsAuthenticateResponse\"7\x82\xd3\xe4\x93\x02\x31\x12//identity-management/v1.0.0/authenticate/status\x12\x8c\x01\n\x07getUser\x12-.org.apache.custos.identity.service.AuthToken\x1a(.org.apache.custos.identity.service.User\"(\x82\xd3\xe4\x93\x02\"\x12 /identity-management/v1.0.0/user\x12\xd3\x01\n*getUserManagementServiceAccountAccessToken\x12\x43.org.apache.custos.identity.service.GetUserManagementSATokenRequest\x1a-.org.apache.custos.identity.service.AuthToken\"1\x82\xd3\xe4\x93\x02+\x12)/identity-management/v1.0.0/account/token\x12\xbe\x01\n\x0e\x65ndUserSession\x12@.org.apache.custos.identity.management.service.EndSessionRequest\x1a\x33.org.apache.custos.identity.service.OperationStatus\"5\x82\xd3\xe4\x93\x02/\"\'/identity-management/v1.0.0/user/logout:\x04\x62ody\x12\xc5\x01\n\tauthorize\x12\x43.org.apache.custos.identity.management.service.AuthorizationRequest\x1a\x44.org.apache.custos.identity.management.service.AuthorizationResponse\"-\x82\xd3\xe4\x93\x02\'\x12%/identity-management/v1.0.0/authorize\x12\x80\x01\n\x05token\x12\x33.org.apache.custos.identity.service.GetTokenRequest\x1a\x17.google.protobuf.Struct\")\x82\xd3\xe4\x93\x02#\"!/identity-management/v1.0.0/token\x12\xc0\x01\n\x0egetCredentials\x12\x44.org.apache.custos.identity.management.service.GetCredentialsRequest\x1a\x37.org.apache.custos.credential.store.service.Credentials\"/\x82\xd3\xe4\x93\x02)\x12\'/identity-management/v1.0.0/credentials\x12\xaf\x01\n\x14getOIDCConfiguration\x12\x38.org.apache.custos.identity.service.GetOIDCConfiguration\x1a\x17.google.protobuf.Struct\"D\x82\xd3\xe4\x93\x02>\x12</identity-management/v1.0.0/.well-known/openid-configuration\x12\xaa\x01\n\rgetAgentToken\x12\x43.org.apache.custos.identity.management.service.GetAgentTokenRequest\x1a\x17.google.protobuf.Struct\";\x82\xd3\xe4\x93\x02\x35\"3/identity-management/v1.0.0/agent/token/{client_id}\x12\xcc\x01\n\x0f\x65ndAgentSession\x12@.org.apache.custos.identity.management.service.EndSessionRequest\x1a\x33.org.apache.custos.identity.service.OperationStatus\"B\x82\xd3\xe4\x93\x02<\"4/identity-management/v1.0.0/agent/logout/{client_id}:\x04\x62odyB\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,IdentityService__pb2.DESCRIPTOR,google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,google_dot_protobuf_dot_any__pb2.DESCRIPTOR,CredentialStoreService__pb2.DESCRIPTOR,])
+
+
+
+
+_AUTHORIZATIONREQUEST = _descriptor.Descriptor(
+  name='AuthorizationRequest',
+  full_name='org.apache.custos.identity.management.service.AuthorizationRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.identity.management.service.AuthorizationRequest.tenant_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.identity.management.service.AuthorizationRequest.client_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_secret', full_name='org.apache.custos.identity.management.service.AuthorizationRequest.client_secret', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='redirect_uri', full_name='org.apache.custos.identity.management.service.AuthorizationRequest.redirect_uri', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='response_type', full_name='org.apache.custos.identity.management.service.AuthorizationRequest.response_type', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.identity.management.service.AuthorizationRequest.scope', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='state', full_name='org.apache.custos.identity.management.service.AuthorizationRequest.state', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=223,
+  serialized_end=381,
+)
+
+
+_AUTHORIZATIONRESPONSE = _descriptor.Descriptor(
+  name='AuthorizationResponse',
+  full_name='org.apache.custos.identity.management.service.AuthorizationResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='loginURI', full_name='org.apache.custos.identity.management.service.AuthorizationResponse.loginURI', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=383,
+  serialized_end=424,
+)
+
+
+_GETCREDENTIALSREQUEST = _descriptor.Descriptor(
+  name='GetCredentialsRequest',
+  full_name='org.apache.custos.identity.management.service.GetCredentialsRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.identity.management.service.GetCredentialsRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='credentials', full_name='org.apache.custos.identity.management.service.GetCredentialsRequest.credentials', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=426,
+  serialized_end=546,
+)
+
+
+_GETAGENTTOKENREQUEST = _descriptor.Descriptor(
+  name='GetAgentTokenRequest',
+  full_name='org.apache.custos.identity.management.service.GetAgentTokenRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.identity.management.service.GetAgentTokenRequest.tenant_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='agent_client_id', full_name='org.apache.custos.identity.management.service.GetAgentTokenRequest.agent_client_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='agent_client_secret', full_name='org.apache.custos.identity.management.service.GetAgentTokenRequest.agent_client_secret', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='agentId', full_name='org.apache.custos.identity.management.service.GetAgentTokenRequest.agentId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='agentPassword', full_name='org.apache.custos.identity.management.service.GetAgentTokenRequest.agentPassword', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.identity.management.service.GetAgentTokenRequest.client_id', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='grant_type', full_name='org.apache.custos.identity.management.service.GetAgentTokenRequest.grant_type', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='refresh_token', full_name='org.apache.custos.identity.management.service.GetAgentTokenRequest.refresh_token', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=549,
+  serialized_end=746,
+)
+
+
+_ENDSESSIONREQUEST = _descriptor.Descriptor(
+  name='EndSessionRequest',
+  full_name='org.apache.custos.identity.management.service.EndSessionRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.identity.management.service.EndSessionRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='body', full_name='org.apache.custos.identity.management.service.EndSessionRequest.body', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=748,
+  serialized_end=855,
+)
+
+_GETCREDENTIALSREQUEST.fields_by_name['credentials'].message_type = CredentialStoreService__pb2._CREDENTIALS
+_ENDSESSIONREQUEST.fields_by_name['body'].message_type = IdentityService__pb2._ENDSESSIONREQUEST
+DESCRIPTOR.message_types_by_name['AuthorizationRequest'] = _AUTHORIZATIONREQUEST
+DESCRIPTOR.message_types_by_name['AuthorizationResponse'] = _AUTHORIZATIONRESPONSE
+DESCRIPTOR.message_types_by_name['GetCredentialsRequest'] = _GETCREDENTIALSREQUEST
+DESCRIPTOR.message_types_by_name['GetAgentTokenRequest'] = _GETAGENTTOKENREQUEST
+DESCRIPTOR.message_types_by_name['EndSessionRequest'] = _ENDSESSIONREQUEST
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+AuthorizationRequest = _reflection.GeneratedProtocolMessageType('AuthorizationRequest', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHORIZATIONREQUEST,
+  '__module__' : 'IdentityManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.management.service.AuthorizationRequest)
+  })
+_sym_db.RegisterMessage(AuthorizationRequest)
+
+AuthorizationResponse = _reflection.GeneratedProtocolMessageType('AuthorizationResponse', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHORIZATIONRESPONSE,
+  '__module__' : 'IdentityManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.management.service.AuthorizationResponse)
+  })
+_sym_db.RegisterMessage(AuthorizationResponse)
+
+GetCredentialsRequest = _reflection.GeneratedProtocolMessageType('GetCredentialsRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETCREDENTIALSREQUEST,
+  '__module__' : 'IdentityManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.management.service.GetCredentialsRequest)
+  })
+_sym_db.RegisterMessage(GetCredentialsRequest)
+
+GetAgentTokenRequest = _reflection.GeneratedProtocolMessageType('GetAgentTokenRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETAGENTTOKENREQUEST,
+  '__module__' : 'IdentityManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.management.service.GetAgentTokenRequest)
+  })
+_sym_db.RegisterMessage(GetAgentTokenRequest)
+
+EndSessionRequest = _reflection.GeneratedProtocolMessageType('EndSessionRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ENDSESSIONREQUEST,
+  '__module__' : 'IdentityManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.identity.management.service.EndSessionRequest)
+  })
+_sym_db.RegisterMessage(EndSessionRequest)
+
+
+DESCRIPTOR._options = None
+
+_IDENTITYMANAGEMENTSERVICE = _descriptor.ServiceDescriptor(
+  name='IdentityManagementService',
+  full_name='org.apache.custos.identity.management.service.IdentityManagementService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=858,
+  serialized_end=2876,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='authenticate',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.authenticate',
+    index=0,
+    containing_service=None,
+    input_type=IdentityService__pb2._AUTHENTICATIONREQUEST,
+    output_type=IdentityService__pb2._AUTHTOKEN,
+    serialized_options=b'\202\323\344\223\002*\"(/identity-management/v1.0.0/authenticate',
+  ),
+  _descriptor.MethodDescriptor(
+    name='isAuthenticated',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.isAuthenticated',
+    index=1,
+    containing_service=None,
+    input_type=IdentityService__pb2._AUTHTOKEN,
+    output_type=IdentityService__pb2._ISAUTHENTICATERESPONSE,
+    serialized_options=b'\202\323\344\223\0021\022//identity-management/v1.0.0/authenticate/status',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUser',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.getUser',
+    index=2,
+    containing_service=None,
+    input_type=IdentityService__pb2._AUTHTOKEN,
+    output_type=IdentityService__pb2._USER,
+    serialized_options=b'\202\323\344\223\002\"\022 /identity-management/v1.0.0/user',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUserManagementServiceAccountAccessToken',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.getUserManagementServiceAccountAccessToken',
+    index=3,
+    containing_service=None,
+    input_type=IdentityService__pb2._GETUSERMANAGEMENTSATOKENREQUEST,
+    output_type=IdentityService__pb2._AUTHTOKEN,
+    serialized_options=b'\202\323\344\223\002+\022)/identity-management/v1.0.0/account/token',
+  ),
+  _descriptor.MethodDescriptor(
+    name='endUserSession',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.endUserSession',
+    index=4,
+    containing_service=None,
+    input_type=_ENDSESSIONREQUEST,
+    output_type=IdentityService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002/\"\'/identity-management/v1.0.0/user/logout:\004body',
+  ),
+  _descriptor.MethodDescriptor(
+    name='authorize',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.authorize',
+    index=5,
+    containing_service=None,
+    input_type=_AUTHORIZATIONREQUEST,
+    output_type=_AUTHORIZATIONRESPONSE,
+    serialized_options=b'\202\323\344\223\002\'\022%/identity-management/v1.0.0/authorize',
+  ),
+  _descriptor.MethodDescriptor(
+    name='token',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.token',
+    index=6,
+    containing_service=None,
+    input_type=IdentityService__pb2._GETTOKENREQUEST,
+    output_type=google_dot_protobuf_dot_struct__pb2._STRUCT,
+    serialized_options=b'\202\323\344\223\002#\"!/identity-management/v1.0.0/token',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getCredentials',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.getCredentials',
+    index=7,
+    containing_service=None,
+    input_type=_GETCREDENTIALSREQUEST,
+    output_type=CredentialStoreService__pb2._CREDENTIALS,
+    serialized_options=b'\202\323\344\223\002)\022\'/identity-management/v1.0.0/credentials',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getOIDCConfiguration',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.getOIDCConfiguration',
+    index=8,
+    containing_service=None,
+    input_type=IdentityService__pb2._GETOIDCCONFIGURATION,
+    output_type=google_dot_protobuf_dot_struct__pb2._STRUCT,
+    serialized_options=b'\202\323\344\223\002>\022</identity-management/v1.0.0/.well-known/openid-configuration',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAgentToken',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.getAgentToken',
+    index=9,
+    containing_service=None,
+    input_type=_GETAGENTTOKENREQUEST,
+    output_type=google_dot_protobuf_dot_struct__pb2._STRUCT,
+    serialized_options=b'\202\323\344\223\0025\"3/identity-management/v1.0.0/agent/token/{client_id}',
+  ),
+  _descriptor.MethodDescriptor(
+    name='endAgentSession',
+    full_name='org.apache.custos.identity.management.service.IdentityManagementService.endAgentSession',
+    index=10,
+    containing_service=None,
+    input_type=_ENDSESSIONREQUEST,
+    output_type=IdentityService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002<\"4/identity-management/v1.0.0/agent/logout/{client_id}:\004body',
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_IDENTITYMANAGEMENTSERVICE)
+
+DESCRIPTOR.services_by_name['IdentityManagementService'] = _IDENTITYMANAGEMENTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/IdentityManagementService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/IdentityManagementService_pb2_grpc.py
new file mode 100644
index 0000000..eae4ee1
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/IdentityManagementService_pb2_grpc.py
@@ -0,0 +1,219 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import custos.server.core.CredentialStoreService_pb2 as CredentialStoreService__pb2
+import custos.server.integration.IdentityManagementService_pb2 as IdentityManagementService__pb2
+import custos.server.core.IdentityService_pb2 as IdentityService__pb2
+from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
+
+
+class IdentityManagementServiceStub(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.authenticate = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/authenticate',
+        request_serializer=IdentityService__pb2.AuthenticationRequest.SerializeToString,
+        response_deserializer=IdentityService__pb2.AuthToken.FromString,
+        )
+    self.isAuthenticated = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/isAuthenticated',
+        request_serializer=IdentityService__pb2.AuthToken.SerializeToString,
+        response_deserializer=IdentityService__pb2.IsAuthenticateResponse.FromString,
+        )
+    self.getUser = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/getUser',
+        request_serializer=IdentityService__pb2.AuthToken.SerializeToString,
+        response_deserializer=IdentityService__pb2.User.FromString,
+        )
+    self.getUserManagementServiceAccountAccessToken = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/getUserManagementServiceAccountAccessToken',
+        request_serializer=IdentityService__pb2.GetUserManagementSATokenRequest.SerializeToString,
+        response_deserializer=IdentityService__pb2.AuthToken.FromString,
+        )
+    self.endUserSession = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/endUserSession',
+        request_serializer=IdentityManagementService__pb2.EndSessionRequest.SerializeToString,
+        response_deserializer=IdentityService__pb2.OperationStatus.FromString,
+        )
+    self.authorize = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/authorize',
+        request_serializer=IdentityManagementService__pb2.AuthorizationRequest.SerializeToString,
+        response_deserializer=IdentityManagementService__pb2.AuthorizationResponse.FromString,
+        )
+    self.token = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/token',
+        request_serializer=IdentityService__pb2.GetTokenRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+        )
+    self.getCredentials = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/getCredentials',
+        request_serializer=IdentityManagementService__pb2.GetCredentialsRequest.SerializeToString,
+        response_deserializer=CredentialStoreService__pb2.Credentials.FromString,
+        )
+    self.getOIDCConfiguration = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/getOIDCConfiguration',
+        request_serializer=IdentityService__pb2.GetOIDCConfiguration.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+        )
+    self.getAgentToken = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/getAgentToken',
+        request_serializer=IdentityManagementService__pb2.GetAgentTokenRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+        )
+    self.endAgentSession = channel.unary_unary(
+        '/org.apache.custos.identity.management.service.IdentityManagementService/endAgentSession',
+        request_serializer=IdentityManagementService__pb2.EndSessionRequest.SerializeToString,
+        response_deserializer=IdentityService__pb2.OperationStatus.FromString,
+        )
+
+
+class IdentityManagementServiceServicer(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def authenticate(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def isAuthenticated(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getUser(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getUserManagementServiceAccountAccessToken(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def endUserSession(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def authorize(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def token(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getCredentials(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getOIDCConfiguration(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAgentToken(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def endAgentSession(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_IdentityManagementServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'authenticate': grpc.unary_unary_rpc_method_handler(
+          servicer.authenticate,
+          request_deserializer=IdentityService__pb2.AuthenticationRequest.FromString,
+          response_serializer=IdentityService__pb2.AuthToken.SerializeToString,
+      ),
+      'isAuthenticated': grpc.unary_unary_rpc_method_handler(
+          servicer.isAuthenticated,
+          request_deserializer=IdentityService__pb2.AuthToken.FromString,
+          response_serializer=IdentityService__pb2.IsAuthenticateResponse.SerializeToString,
+      ),
+      'getUser': grpc.unary_unary_rpc_method_handler(
+          servicer.getUser,
+          request_deserializer=IdentityService__pb2.AuthToken.FromString,
+          response_serializer=IdentityService__pb2.User.SerializeToString,
+      ),
+      'getUserManagementServiceAccountAccessToken': grpc.unary_unary_rpc_method_handler(
+          servicer.getUserManagementServiceAccountAccessToken,
+          request_deserializer=IdentityService__pb2.GetUserManagementSATokenRequest.FromString,
+          response_serializer=IdentityService__pb2.AuthToken.SerializeToString,
+      ),
+      'endUserSession': grpc.unary_unary_rpc_method_handler(
+          servicer.endUserSession,
+          request_deserializer=IdentityManagementService__pb2.EndSessionRequest.FromString,
+          response_serializer=IdentityService__pb2.OperationStatus.SerializeToString,
+      ),
+      'authorize': grpc.unary_unary_rpc_method_handler(
+          servicer.authorize,
+          request_deserializer=IdentityManagementService__pb2.AuthorizationRequest.FromString,
+          response_serializer=IdentityManagementService__pb2.AuthorizationResponse.SerializeToString,
+      ),
+      'token': grpc.unary_unary_rpc_method_handler(
+          servicer.token,
+          request_deserializer=IdentityService__pb2.GetTokenRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_struct__pb2.Struct.SerializeToString,
+      ),
+      'getCredentials': grpc.unary_unary_rpc_method_handler(
+          servicer.getCredentials,
+          request_deserializer=IdentityManagementService__pb2.GetCredentialsRequest.FromString,
+          response_serializer=CredentialStoreService__pb2.Credentials.SerializeToString,
+      ),
+      'getOIDCConfiguration': grpc.unary_unary_rpc_method_handler(
+          servicer.getOIDCConfiguration,
+          request_deserializer=IdentityService__pb2.GetOIDCConfiguration.FromString,
+          response_serializer=google_dot_protobuf_dot_struct__pb2.Struct.SerializeToString,
+      ),
+      'getAgentToken': grpc.unary_unary_rpc_method_handler(
+          servicer.getAgentToken,
+          request_deserializer=IdentityManagementService__pb2.GetAgentTokenRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_struct__pb2.Struct.SerializeToString,
+      ),
+      'endAgentSession': grpc.unary_unary_rpc_method_handler(
+          servicer.endAgentSession,
+          request_deserializer=IdentityManagementService__pb2.EndSessionRequest.FromString,
+          response_serializer=IdentityService__pb2.OperationStatus.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.custos.identity.management.service.IdentityManagementService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/ResourceSecretManagementService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/ResourceSecretManagementService_pb2.py
new file mode 100644
index 0000000..d2b0f2f
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/ResourceSecretManagementService_pb2.py
@@ -0,0 +1,183 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: ResourceSecretManagementService.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
+import custos.server.core.ResourceSecretService_pb2 as ResourceSecretService__pb2
+import custos.server.core.IdentityService_pb2 as IdentityService__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='ResourceSecretManagementService.proto',
+  package='org.apache.custos.resource.secret.management.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n%ResourceSecretManagementService.proto\x12\x34org.apache.custos.resource.secret.management.service\x1a\x1cgoogle/api/annotations.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1bResourceSecretService.proto\x1a\x15IdentityService.proto2\xf4\x16\n\x1fResourceSecretManagementService\x12\xb6\x01\n\tgetSecret\x12;.org.apache.custos.resource.secret.service.GetSecretRequest\x1a\x39.org.apache.custos.resource.secret.service.SecretMetadata\"1\x82\xd3\xe4\x93\x02+\x12)/resource-secret-management/v1.0.0/secret\x12\x97\x01\n\x07getJWKS\x12\x32.org.apache.custos.identity.service.GetJWKSRequest\x1a\x17.google.protobuf.Struct\"?\x82\xd3\xe4\x93\x02\x39\x12\x37/resource-secret-management/v1.0.0/openid-connect/certs\x12\xe4\x01\n\x1cgetResourceCredentialSummary\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1a\x39.org.apache.custos.resource.secret.service.SecretMetadata\"9\x82\xd3\xe4\x93\x02\x33\x12\x31/resource-secret-management/v1.0.0/secret/summary\x12\xfa\x01\n!getAllResourceCredentialSummaries\x12P.org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest\x1a\x46.org.apache.custos.resource.secret.service.ResourceCredentialSummaries\";\x82\xd3\xe4\x93\x02\x35\x12\x33/resource-secret-management/v1.0.0/secret/summaries\x12\xcd\x01\n\x10\x61\x64\x64SSHCredential\x12\x38.org.apache.custos.resource.secret.service.SSHCredential\x1aH.org.apache.custos.resource.secret.service.AddResourceCredentialResponse\"5\x82\xd3\xe4\x93\x02/\"-/resource-secret-management/v1.0.0/secret/ssh\x12\xdc\x01\n\x15\x61\x64\x64PasswordCredential\x12=.org.apache.custos.resource.secret.service.PasswordCredential\x1aH.org.apache.custos.resource.secret.service.AddResourceCredentialResponse\":\x82\xd3\xe4\x93\x02\x34\"2/resource-secret-management/v1.0.0/secret/password\x12\xe5\x01\n\x18\x61\x64\x64\x43\x65rtificateCredential\x12@.org.apache.custos.resource.secret.service.CertificateCredential\x1aH.org.apache.custos.resource.secret.service.AddResourceCredentialResponse\"=\x82\xd3\xe4\x93\x02\x37\"5/resource-secret-management/v1.0.0/secret/certificate\x12\xd3\x01\n\x10getSSHCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1a\x38.org.apache.custos.resource.secret.service.SSHCredential\"5\x82\xd3\xe4\x93\x02/\x12-/resource-secret-management/v1.0.0/secret/ssh\x12\xe2\x01\n\x15getPasswordCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1a=.org.apache.custos.resource.secret.service.PasswordCredential\":\x82\xd3\xe4\x93\x02\x34\x12\x32/resource-secret-management/v1.0.0/secret/password\x12\xeb\x01\n\x18getCertificateCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1a@.org.apache.custos.resource.secret.service.CertificateCredential\"=\x82\xd3\xe4\x93\x02\x37\x12\x35/resource-secret-management/v1.0.0/secret/certificate\x12\xea\x01\n\x13\x64\x65leteSSHCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1aL.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus\"5\x82\xd3\xe4\x93\x02/*-/resource-secret-management/v1.0.0/secret/ssh\x12\xef\x01\n\x13\x64\x65letePWDCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1aL.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus\":\x82\xd3\xe4\x93\x02\x34*2/resource-secret-management/v1.0.0/secret/password\x12\xfa\x01\n\x1b\x64\x65leteCertificateCredential\x12N.org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest\x1aL.org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus\"=\x82\xd3\xe4\x93\x02\x37*5/resource-secret-management/v1.0.0/secret/certificateB\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,ResourceSecretService__pb2.DESCRIPTOR,IdentityService__pb2.DESCRIPTOR,])
+
+
+
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+DESCRIPTOR._options = None
+
+_RESOURCESECRETMANAGEMENTSERVICE = _descriptor.ServiceDescriptor(
+  name='ResourceSecretManagementService',
+  full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=237,
+  serialized_end=3169,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='getSecret',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.getSecret',
+    index=0,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._GETSECRETREQUEST,
+    output_type=ResourceSecretService__pb2._SECRETMETADATA,
+    serialized_options=b'\202\323\344\223\002+\022)/resource-secret-management/v1.0.0/secret',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getJWKS',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.getJWKS',
+    index=1,
+    containing_service=None,
+    input_type=IdentityService__pb2._GETJWKSREQUEST,
+    output_type=google_dot_protobuf_dot_struct__pb2._STRUCT,
+    serialized_options=b'\202\323\344\223\0029\0227/resource-secret-management/v1.0.0/openid-connect/certs',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getResourceCredentialSummary',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.getResourceCredentialSummary',
+    index=2,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=ResourceSecretService__pb2._SECRETMETADATA,
+    serialized_options=b'\202\323\344\223\0023\0221/resource-secret-management/v1.0.0/secret/summary',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllResourceCredentialSummaries',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.getAllResourceCredentialSummaries',
+    index=3,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._GETRESOURCECREDENTIALSUMMARIESREQUEST,
+    output_type=ResourceSecretService__pb2._RESOURCECREDENTIALSUMMARIES,
+    serialized_options=b'\202\323\344\223\0025\0223/resource-secret-management/v1.0.0/secret/summaries',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addSSHCredential',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.addSSHCredential',
+    index=4,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._SSHCREDENTIAL,
+    output_type=ResourceSecretService__pb2._ADDRESOURCECREDENTIALRESPONSE,
+    serialized_options=b'\202\323\344\223\002/\"-/resource-secret-management/v1.0.0/secret/ssh',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addPasswordCredential',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.addPasswordCredential',
+    index=5,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._PASSWORDCREDENTIAL,
+    output_type=ResourceSecretService__pb2._ADDRESOURCECREDENTIALRESPONSE,
+    serialized_options=b'\202\323\344\223\0024\"2/resource-secret-management/v1.0.0/secret/password',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addCertificateCredential',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.addCertificateCredential',
+    index=6,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._CERTIFICATECREDENTIAL,
+    output_type=ResourceSecretService__pb2._ADDRESOURCECREDENTIALRESPONSE,
+    serialized_options=b'\202\323\344\223\0027\"5/resource-secret-management/v1.0.0/secret/certificate',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getSSHCredential',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.getSSHCredential',
+    index=7,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=ResourceSecretService__pb2._SSHCREDENTIAL,
+    serialized_options=b'\202\323\344\223\002/\022-/resource-secret-management/v1.0.0/secret/ssh',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getPasswordCredential',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.getPasswordCredential',
+    index=8,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=ResourceSecretService__pb2._PASSWORDCREDENTIAL,
+    serialized_options=b'\202\323\344\223\0024\0222/resource-secret-management/v1.0.0/secret/password',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getCertificateCredential',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.getCertificateCredential',
+    index=9,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=ResourceSecretService__pb2._CERTIFICATECREDENTIAL,
+    serialized_options=b'\202\323\344\223\0027\0225/resource-secret-management/v1.0.0/secret/certificate',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteSSHCredential',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.deleteSSHCredential',
+    index=10,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=ResourceSecretService__pb2._RESOURCECREDENTIALOPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002/*-/resource-secret-management/v1.0.0/secret/ssh',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deletePWDCredential',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.deletePWDCredential',
+    index=11,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=ResourceSecretService__pb2._RESOURCECREDENTIALOPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\0024*2/resource-secret-management/v1.0.0/secret/password',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteCertificateCredential',
+    full_name='org.apache.custos.resource.secret.management.service.ResourceSecretManagementService.deleteCertificateCredential',
+    index=12,
+    containing_service=None,
+    input_type=ResourceSecretService__pb2._GETRESOURCECREDENTIALBYTOKENREQUEST,
+    output_type=ResourceSecretService__pb2._RESOURCECREDENTIALOPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\0027*5/resource-secret-management/v1.0.0/secret/certificate',
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_RESOURCESECRETMANAGEMENTSERVICE)
+
+DESCRIPTOR.services_by_name['ResourceSecretManagementService'] = _RESOURCESECRETMANAGEMENTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/ResourceSecretManagementService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/ResourceSecretManagementService_pb2_grpc.py
new file mode 100644
index 0000000..46f4569
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/ResourceSecretManagementService_pb2_grpc.py
@@ -0,0 +1,464 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import custos.server.core.IdentityService_pb2 as IdentityService__pb2
+import custos.server.core.ResourceSecretService_pb2 as ResourceSecretService__pb2
+from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
+
+
+class ResourceSecretManagementServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.getSecret = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSecret',
+                request_serializer=ResourceSecretService__pb2.GetSecretRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.SecretMetadata.FromString,
+                )
+        self.getJWKS = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getJWKS',
+                request_serializer=IdentityService__pb2.GetJWKSRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+                )
+        self.getResourceCredentialSummary = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getResourceCredentialSummary',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.SecretMetadata.FromString,
+                )
+        self.getAllResourceCredentialSummaries = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getAllResourceCredentialSummaries',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialSummariesRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.ResourceCredentialSummaries.FromString,
+                )
+        self.addSSHCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addSSHCredential',
+                request_serializer=ResourceSecretService__pb2.SSHCredential.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+                )
+        self.addPasswordCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addPasswordCredential',
+                request_serializer=ResourceSecretService__pb2.PasswordCredential.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+                )
+        self.addCertificateCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addCertificateCredential',
+                request_serializer=ResourceSecretService__pb2.CertificateCredential.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+                )
+        self.getSSHCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSSHCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.SSHCredential.FromString,
+                )
+        self.getPasswordCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getPasswordCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.PasswordCredential.FromString,
+                )
+        self.getCertificateCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getCertificateCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.CertificateCredential.FromString,
+                )
+        self.deleteSSHCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteSSHCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+                )
+        self.deletePWDCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deletePWDCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+                )
+        self.deleteCertificateCredential = channel.unary_unary(
+                '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteCertificateCredential',
+                request_serializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+                response_deserializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+                )
+
+
+class ResourceSecretManagementServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def getSecret(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getJWKS(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getResourceCredentialSummary(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllResourceCredentialSummaries(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addSSHCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addPasswordCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addCertificateCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getSSHCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getPasswordCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getCertificateCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteSSHCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deletePWDCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteCertificateCredential(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_ResourceSecretManagementServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'getSecret': grpc.unary_unary_rpc_method_handler(
+                    servicer.getSecret,
+                    request_deserializer=ResourceSecretService__pb2.GetSecretRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.SecretMetadata.SerializeToString,
+            ),
+            'getJWKS': grpc.unary_unary_rpc_method_handler(
+                    servicer.getJWKS,
+                    request_deserializer=IdentityService__pb2.GetJWKSRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_struct__pb2.Struct.SerializeToString,
+            ),
+            'getResourceCredentialSummary': grpc.unary_unary_rpc_method_handler(
+                    servicer.getResourceCredentialSummary,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.SecretMetadata.SerializeToString,
+            ),
+            'getAllResourceCredentialSummaries': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllResourceCredentialSummaries,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialSummariesRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.ResourceCredentialSummaries.SerializeToString,
+            ),
+            'addSSHCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.addSSHCredential,
+                    request_deserializer=ResourceSecretService__pb2.SSHCredential.FromString,
+                    response_serializer=ResourceSecretService__pb2.AddResourceCredentialResponse.SerializeToString,
+            ),
+            'addPasswordCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.addPasswordCredential,
+                    request_deserializer=ResourceSecretService__pb2.PasswordCredential.FromString,
+                    response_serializer=ResourceSecretService__pb2.AddResourceCredentialResponse.SerializeToString,
+            ),
+            'addCertificateCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.addCertificateCredential,
+                    request_deserializer=ResourceSecretService__pb2.CertificateCredential.FromString,
+                    response_serializer=ResourceSecretService__pb2.AddResourceCredentialResponse.SerializeToString,
+            ),
+            'getSSHCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.getSSHCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.SSHCredential.SerializeToString,
+            ),
+            'getPasswordCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.getPasswordCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.PasswordCredential.SerializeToString,
+            ),
+            'getCertificateCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.getCertificateCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.CertificateCredential.SerializeToString,
+            ),
+            'deleteSSHCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteSSHCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.SerializeToString,
+            ),
+            'deletePWDCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.deletePWDCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.SerializeToString,
+            ),
+            'deleteCertificateCredential': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteCertificateCredential,
+                    request_deserializer=ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.FromString,
+                    response_serializer=ResourceSecretService__pb2.ResourceCredentialOperationStatus.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'org.apache.custos.resource.secret.management.service.ResourceSecretManagementService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class ResourceSecretManagementService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def getSecret(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSecret',
+            ResourceSecretService__pb2.GetSecretRequest.SerializeToString,
+            ResourceSecretService__pb2.SecretMetadata.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getJWKS(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getJWKS',
+            IdentityService__pb2.GetJWKSRequest.SerializeToString,
+            google_dot_protobuf_dot_struct__pb2.Struct.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getResourceCredentialSummary(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getResourceCredentialSummary',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.SecretMetadata.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllResourceCredentialSummaries(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getAllResourceCredentialSummaries',
+            ResourceSecretService__pb2.GetResourceCredentialSummariesRequest.SerializeToString,
+            ResourceSecretService__pb2.ResourceCredentialSummaries.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addSSHCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addSSHCredential',
+            ResourceSecretService__pb2.SSHCredential.SerializeToString,
+            ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addPasswordCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addPasswordCredential',
+            ResourceSecretService__pb2.PasswordCredential.SerializeToString,
+            ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addCertificateCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/addCertificateCredential',
+            ResourceSecretService__pb2.CertificateCredential.SerializeToString,
+            ResourceSecretService__pb2.AddResourceCredentialResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getSSHCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getSSHCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.SSHCredential.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getPasswordCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getPasswordCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.PasswordCredential.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getCertificateCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/getCertificateCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.CertificateCredential.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteSSHCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteSSHCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deletePWDCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deletePWDCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteCertificateCredential(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService/deleteCertificateCredential',
+            ResourceSecretService__pb2.GetResourceCredentialByTokenRequest.SerializeToString,
+            ResourceSecretService__pb2.ResourceCredentialOperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/SharingManagementService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/SharingManagementService_pb2.py
new file mode 100644
index 0000000..601e34d
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/SharingManagementService_pb2.py
@@ -0,0 +1,300 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: SharingManagementService.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+import custos.server.core.SharingService_pb2 as SharingService__pb2
+from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='SharingManagementService.proto',
+  package='org.apache.custos.sharing.management.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x1eSharingManagementService.proto\x12,org.apache.custos.sharing.management.service\x1a\x14SharingService.proto\x1a\x1cgoogle/api/annotations.proto2\xaa!\n\x18SharingManagementService\x12\xa3\x01\n\x10\x63reateEntityType\x12\x34.org.apache.custos.sharing.service.EntityTypeRequest\x1a).org.apache.custos.sharing.service.Status\".\x82\xd3\xe4\x93\x02(\"&/sharing-management/v1.0.0/entity/type\x12\xa3\x01\n\x10updateEntityType\x12\x34.org.apache.custos.sharing.service.EntityTypeRequest\x1a).org.apache.custos.sharing.service.Status\".\x82\xd3\xe4\x93\x02(\x1a&/sharing-management/v1.0.0/entity/type\x12\xa3\x01\n\x10\x64\x65leteEntityType\x12\x34.org.apache.custos.sharing.service.EntityTypeRequest\x1a).org.apache.custos.sharing.service.Status\".\x82\xd3\xe4\x93\x02(*&/sharing-management/v1.0.0/entity/type\x12\xa4\x01\n\rgetEntityType\x12\x34.org.apache.custos.sharing.service.EntityTypeRequest\x1a-.org.apache.custos.sharing.service.EntityType\".\x82\xd3\xe4\x93\x02(\x12&/sharing-management/v1.0.0/entity/type\x12\xa3\x01\n\x0egetEntityTypes\x12\x30.org.apache.custos.sharing.service.SearchRequest\x1a..org.apache.custos.sharing.service.EntityTypes\"/\x82\xd3\xe4\x93\x02)\x12\'/sharing-management/v1.0.0/entity/types\x12\xaf\x01\n\x14\x63reatePermissionType\x12\x38.org.apache.custos.sharing.service.PermissionTypeRequest\x1a).org.apache.custos.sharing.service.Status\"2\x82\xd3\xe4\x93\x02,\"*/sharing-management/v1.0.0/permission/type\x12\xaf\x01\n\x14updatePermissionType\x12\x38.org.apache.custos.sharing.service.PermissionTypeRequest\x1a).org.apache.custos.sharing.service.Status\"2\x82\xd3\xe4\x93\x02,\x1a*/sharing-management/v1.0.0/permission/type\x12\xaf\x01\n\x14\x64\x65letePermissionType\x12\x38.org.apache.custos.sharing.service.PermissionTypeRequest\x1a).org.apache.custos.sharing.service.Status\"2\x82\xd3\xe4\x93\x02,**/sharing-management/v1.0.0/permission/type\x12\xb4\x01\n\x11getPermissionType\x12\x38.org.apache.custos.sharing.service.PermissionTypeRequest\x1a\x31.org.apache.custos.sharing.service.PermissionType\"2\x82\xd3\xe4\x93\x02,\x12*/sharing-management/v1.0.0/permission/type\x12\xaf\x01\n\x12getPermissionTypes\x12\x30.org.apache.custos.sharing.service.SearchRequest\x1a\x32.org.apache.custos.sharing.service.PermissionTypes\"3\x82\xd3\xe4\x93\x02-\x12+/sharing-management/v1.0.0/permission/types\x12\x96\x01\n\x0c\x63reateEntity\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Status\")\x82\xd3\xe4\x93\x02#\"!/sharing-management/v1.0.0/entity\x12\x96\x01\n\x0cupdateEntity\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Status\")\x82\xd3\xe4\x93\x02#\x1a!/sharing-management/v1.0.0/entity\x12\xa2\x01\n\x0eisEntityExists\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Status\"3\x82\xd3\xe4\x93\x02-\x12+/sharing-management/v1.0.0/entity/existence\x12\x93\x01\n\tgetEntity\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Entity\")\x82\xd3\xe4\x93\x02#\x12!/sharing-management/v1.0.0/entity\x12\x96\x01\n\x0c\x64\x65leteEntity\x12\x30.org.apache.custos.sharing.service.EntityRequest\x1a).org.apache.custos.sharing.service.Status\")\x82\xd3\xe4\x93\x02#*!/sharing-management/v1.0.0/entity\x12\x9c\x01\n\x0esearchEntities\x12\x30.org.apache.custos.sharing.service.SearchRequest\x1a+.org.apache.custos.sharing.service.Entities\"+\x82\xd3\xe4\x93\x02%\"#/sharing-management/v1.0.0/entities\x12\xaa\x01\n\x14getListOfSharedUsers\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a/.org.apache.custos.sharing.service.SharedOwners\".\x82\xd3\xe4\x93\x02(\x12&/sharing-management/v1.0.0/users/share\x12\xb9\x01\n\x1cgetListOfDirectlySharedUsers\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a/.org.apache.custos.sharing.service.SharedOwners\"5\x82\xd3\xe4\x93\x02/\x12-/sharing-management/v1.0.0/users/share/direct\x12\xac\x01\n\x15getListOfSharedGroups\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a/.org.apache.custos.sharing.service.SharedOwners\"/\x82\xd3\xe4\x93\x02)\x12\'/sharing-management/v1.0.0/groups/share\x12\xbb\x01\n\x1dgetListOfDirectlySharedGroups\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a/.org.apache.custos.sharing.service.SharedOwners\"6\x82\xd3\xe4\x93\x02\x30\x12./sharing-management/v1.0.0/groups/share/direct\x12\xa4\x01\n\x14shareEntityWithUsers\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.Status\".\x82\xd3\xe4\x93\x02(\"&/sharing-management/v1.0.0/users/share\x12\xa6\x01\n\x15shareEntityWithGroups\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.Status\"/\x82\xd3\xe4\x93\x02)\"\'/sharing-management/v1.0.0/groups/share\x12\xac\x01\n\x1crevokeEntitySharingFromUsers\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.Status\".\x82\xd3\xe4\x93\x02(*&/sharing-management/v1.0.0/users/share\x12\xae\x01\n\x1drevokeEntitySharingFromGroups\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.Status\"/\x82\xd3\xe4\x93\x02)*\'/sharing-management/v1.0.0/groups/share\x12\xa4\x01\n\ruserHasAccess\x12\x31.org.apache.custos.sharing.service.SharingRequest\x1a).org.apache.custos.sharing.service.Status\"5\x82\xd3\xe4\x93\x02/\x12-/sharing-management/v1.0.0/entity/user/accessB\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[SharingService__pb2.DESCRIPTOR,google_dot_api_dot_annotations__pb2.DESCRIPTOR,])
+
+
+
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+DESCRIPTOR._options = None
+
+_SHARINGMANAGEMENTSERVICE = _descriptor.ServiceDescriptor(
+  name='SharingManagementService',
+  full_name='org.apache.custos.sharing.management.service.SharingManagementService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=133,
+  serialized_end=4399,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='createEntityType',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.createEntityType',
+    index=0,
+    containing_service=None,
+    input_type=SharingService__pb2._ENTITYTYPEREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002(\"&/sharing-management/v1.0.0/entity/type',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateEntityType',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.updateEntityType',
+    index=1,
+    containing_service=None,
+    input_type=SharingService__pb2._ENTITYTYPEREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002(\032&/sharing-management/v1.0.0/entity/type',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteEntityType',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.deleteEntityType',
+    index=2,
+    containing_service=None,
+    input_type=SharingService__pb2._ENTITYTYPEREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002(*&/sharing-management/v1.0.0/entity/type',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getEntityType',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.getEntityType',
+    index=3,
+    containing_service=None,
+    input_type=SharingService__pb2._ENTITYTYPEREQUEST,
+    output_type=SharingService__pb2._ENTITYTYPE,
+    serialized_options=b'\202\323\344\223\002(\022&/sharing-management/v1.0.0/entity/type',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getEntityTypes',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.getEntityTypes',
+    index=4,
+    containing_service=None,
+    input_type=SharingService__pb2._SEARCHREQUEST,
+    output_type=SharingService__pb2._ENTITYTYPES,
+    serialized_options=b'\202\323\344\223\002)\022\'/sharing-management/v1.0.0/entity/types',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createPermissionType',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.createPermissionType',
+    index=5,
+    containing_service=None,
+    input_type=SharingService__pb2._PERMISSIONTYPEREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002,\"*/sharing-management/v1.0.0/permission/type',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updatePermissionType',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.updatePermissionType',
+    index=6,
+    containing_service=None,
+    input_type=SharingService__pb2._PERMISSIONTYPEREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002,\032*/sharing-management/v1.0.0/permission/type',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deletePermissionType',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.deletePermissionType',
+    index=7,
+    containing_service=None,
+    input_type=SharingService__pb2._PERMISSIONTYPEREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002,**/sharing-management/v1.0.0/permission/type',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getPermissionType',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.getPermissionType',
+    index=8,
+    containing_service=None,
+    input_type=SharingService__pb2._PERMISSIONTYPEREQUEST,
+    output_type=SharingService__pb2._PERMISSIONTYPE,
+    serialized_options=b'\202\323\344\223\002,\022*/sharing-management/v1.0.0/permission/type',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getPermissionTypes',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.getPermissionTypes',
+    index=9,
+    containing_service=None,
+    input_type=SharingService__pb2._SEARCHREQUEST,
+    output_type=SharingService__pb2._PERMISSIONTYPES,
+    serialized_options=b'\202\323\344\223\002-\022+/sharing-management/v1.0.0/permission/types',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createEntity',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.createEntity',
+    index=10,
+    containing_service=None,
+    input_type=SharingService__pb2._ENTITYREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002#\"!/sharing-management/v1.0.0/entity',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateEntity',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.updateEntity',
+    index=11,
+    containing_service=None,
+    input_type=SharingService__pb2._ENTITYREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002#\032!/sharing-management/v1.0.0/entity',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isEntityExists',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.isEntityExists',
+    index=12,
+    containing_service=None,
+    input_type=SharingService__pb2._ENTITYREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002-\022+/sharing-management/v1.0.0/entity/existence',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getEntity',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.getEntity',
+    index=13,
+    containing_service=None,
+    input_type=SharingService__pb2._ENTITYREQUEST,
+    output_type=SharingService__pb2._ENTITY,
+    serialized_options=b'\202\323\344\223\002#\022!/sharing-management/v1.0.0/entity',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteEntity',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.deleteEntity',
+    index=14,
+    containing_service=None,
+    input_type=SharingService__pb2._ENTITYREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002#*!/sharing-management/v1.0.0/entity',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='searchEntities',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.searchEntities',
+    index=15,
+    containing_service=None,
+    input_type=SharingService__pb2._SEARCHREQUEST,
+    output_type=SharingService__pb2._ENTITIES,
+    serialized_options=b'\202\323\344\223\002%\"#/sharing-management/v1.0.0/entities',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getListOfSharedUsers',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.getListOfSharedUsers',
+    index=16,
+    containing_service=None,
+    input_type=SharingService__pb2._SHARINGREQUEST,
+    output_type=SharingService__pb2._SHAREDOWNERS,
+    serialized_options=b'\202\323\344\223\002(\022&/sharing-management/v1.0.0/users/share',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getListOfDirectlySharedUsers',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.getListOfDirectlySharedUsers',
+    index=17,
+    containing_service=None,
+    input_type=SharingService__pb2._SHARINGREQUEST,
+    output_type=SharingService__pb2._SHAREDOWNERS,
+    serialized_options=b'\202\323\344\223\002/\022-/sharing-management/v1.0.0/users/share/direct',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getListOfSharedGroups',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.getListOfSharedGroups',
+    index=18,
+    containing_service=None,
+    input_type=SharingService__pb2._SHARINGREQUEST,
+    output_type=SharingService__pb2._SHAREDOWNERS,
+    serialized_options=b'\202\323\344\223\002)\022\'/sharing-management/v1.0.0/groups/share',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getListOfDirectlySharedGroups',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.getListOfDirectlySharedGroups',
+    index=19,
+    containing_service=None,
+    input_type=SharingService__pb2._SHARINGREQUEST,
+    output_type=SharingService__pb2._SHAREDOWNERS,
+    serialized_options=b'\202\323\344\223\0020\022./sharing-management/v1.0.0/groups/share/direct',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='shareEntityWithUsers',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.shareEntityWithUsers',
+    index=20,
+    containing_service=None,
+    input_type=SharingService__pb2._SHARINGREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002(\"&/sharing-management/v1.0.0/users/share',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='shareEntityWithGroups',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.shareEntityWithGroups',
+    index=21,
+    containing_service=None,
+    input_type=SharingService__pb2._SHARINGREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002)\"\'/sharing-management/v1.0.0/groups/share',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='revokeEntitySharingFromUsers',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.revokeEntitySharingFromUsers',
+    index=22,
+    containing_service=None,
+    input_type=SharingService__pb2._SHARINGREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002(*&/sharing-management/v1.0.0/users/share',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='revokeEntitySharingFromGroups',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.revokeEntitySharingFromGroups',
+    index=23,
+    containing_service=None,
+    input_type=SharingService__pb2._SHARINGREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002)*\'/sharing-management/v1.0.0/groups/share',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='userHasAccess',
+    full_name='org.apache.custos.sharing.management.service.SharingManagementService.userHasAccess',
+    index=24,
+    containing_service=None,
+    input_type=SharingService__pb2._SHARINGREQUEST,
+    output_type=SharingService__pb2._STATUS,
+    serialized_options=b'\202\323\344\223\002/\022-/sharing-management/v1.0.0/entity/user/access',
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_SHARINGMANAGEMENTSERVICE)
+
+DESCRIPTOR.services_by_name['SharingManagementService'] = _SHARINGMANAGEMENTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/SharingManagementService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/SharingManagementService_pb2_grpc.py
new file mode 100644
index 0000000..ced0625
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/SharingManagementService_pb2_grpc.py
@@ -0,0 +1,858 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import custos.server.core.SharingService_pb2 as SharingService__pb2
+
+
+class SharingManagementServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.createEntityType = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/createEntityType',
+                request_serializer=SharingService__pb2.EntityTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.updateEntityType = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/updateEntityType',
+                request_serializer=SharingService__pb2.EntityTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.deleteEntityType = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/deleteEntityType',
+                request_serializer=SharingService__pb2.EntityTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.getEntityType = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/getEntityType',
+                request_serializer=SharingService__pb2.EntityTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.EntityType.FromString,
+                )
+        self.getEntityTypes = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/getEntityTypes',
+                request_serializer=SharingService__pb2.SearchRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.EntityTypes.FromString,
+                )
+        self.createPermissionType = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/createPermissionType',
+                request_serializer=SharingService__pb2.PermissionTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.updatePermissionType = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/updatePermissionType',
+                request_serializer=SharingService__pb2.PermissionTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.deletePermissionType = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/deletePermissionType',
+                request_serializer=SharingService__pb2.PermissionTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.getPermissionType = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/getPermissionType',
+                request_serializer=SharingService__pb2.PermissionTypeRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.PermissionType.FromString,
+                )
+        self.getPermissionTypes = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/getPermissionTypes',
+                request_serializer=SharingService__pb2.SearchRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.PermissionTypes.FromString,
+                )
+        self.createEntity = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/createEntity',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.updateEntity = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/updateEntity',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.isEntityExists = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/isEntityExists',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.getEntity = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/getEntity',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Entity.FromString,
+                )
+        self.deleteEntity = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/deleteEntity',
+                request_serializer=SharingService__pb2.EntityRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.searchEntities = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/searchEntities',
+                request_serializer=SharingService__pb2.SearchRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Entities.FromString,
+                )
+        self.getListOfSharedUsers = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/getListOfSharedUsers',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.SharedOwners.FromString,
+                )
+        self.getListOfDirectlySharedUsers = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/getListOfDirectlySharedUsers',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.SharedOwners.FromString,
+                )
+        self.getListOfSharedGroups = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/getListOfSharedGroups',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.SharedOwners.FromString,
+                )
+        self.getListOfDirectlySharedGroups = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/getListOfDirectlySharedGroups',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.SharedOwners.FromString,
+                )
+        self.shareEntityWithUsers = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/shareEntityWithUsers',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.shareEntityWithGroups = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/shareEntityWithGroups',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.revokeEntitySharingFromUsers = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/revokeEntitySharingFromUsers',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.revokeEntitySharingFromGroups = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/revokeEntitySharingFromGroups',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+        self.userHasAccess = channel.unary_unary(
+                '/org.apache.custos.sharing.management.service.SharingManagementService/userHasAccess',
+                request_serializer=SharingService__pb2.SharingRequest.SerializeToString,
+                response_deserializer=SharingService__pb2.Status.FromString,
+                )
+
+
+class SharingManagementServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def createEntityType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateEntityType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteEntityType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getEntityType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getEntityTypes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def createPermissionType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updatePermissionType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deletePermissionType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getPermissionType(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getPermissionTypes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def createEntity(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateEntity(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isEntityExists(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getEntity(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteEntity(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def searchEntities(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getListOfSharedUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getListOfDirectlySharedUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getListOfSharedGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getListOfDirectlySharedGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def shareEntityWithUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def shareEntityWithGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def revokeEntitySharingFromUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def revokeEntitySharingFromGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def userHasAccess(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_SharingManagementServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'createEntityType': grpc.unary_unary_rpc_method_handler(
+                    servicer.createEntityType,
+                    request_deserializer=SharingService__pb2.EntityTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'updateEntityType': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateEntityType,
+                    request_deserializer=SharingService__pb2.EntityTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'deleteEntityType': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteEntityType,
+                    request_deserializer=SharingService__pb2.EntityTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'getEntityType': grpc.unary_unary_rpc_method_handler(
+                    servicer.getEntityType,
+                    request_deserializer=SharingService__pb2.EntityTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.EntityType.SerializeToString,
+            ),
+            'getEntityTypes': grpc.unary_unary_rpc_method_handler(
+                    servicer.getEntityTypes,
+                    request_deserializer=SharingService__pb2.SearchRequest.FromString,
+                    response_serializer=SharingService__pb2.EntityTypes.SerializeToString,
+            ),
+            'createPermissionType': grpc.unary_unary_rpc_method_handler(
+                    servicer.createPermissionType,
+                    request_deserializer=SharingService__pb2.PermissionTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'updatePermissionType': grpc.unary_unary_rpc_method_handler(
+                    servicer.updatePermissionType,
+                    request_deserializer=SharingService__pb2.PermissionTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'deletePermissionType': grpc.unary_unary_rpc_method_handler(
+                    servicer.deletePermissionType,
+                    request_deserializer=SharingService__pb2.PermissionTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'getPermissionType': grpc.unary_unary_rpc_method_handler(
+                    servicer.getPermissionType,
+                    request_deserializer=SharingService__pb2.PermissionTypeRequest.FromString,
+                    response_serializer=SharingService__pb2.PermissionType.SerializeToString,
+            ),
+            'getPermissionTypes': grpc.unary_unary_rpc_method_handler(
+                    servicer.getPermissionTypes,
+                    request_deserializer=SharingService__pb2.SearchRequest.FromString,
+                    response_serializer=SharingService__pb2.PermissionTypes.SerializeToString,
+            ),
+            'createEntity': grpc.unary_unary_rpc_method_handler(
+                    servicer.createEntity,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'updateEntity': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateEntity,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'isEntityExists': grpc.unary_unary_rpc_method_handler(
+                    servicer.isEntityExists,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'getEntity': grpc.unary_unary_rpc_method_handler(
+                    servicer.getEntity,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Entity.SerializeToString,
+            ),
+            'deleteEntity': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteEntity,
+                    request_deserializer=SharingService__pb2.EntityRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'searchEntities': grpc.unary_unary_rpc_method_handler(
+                    servicer.searchEntities,
+                    request_deserializer=SharingService__pb2.SearchRequest.FromString,
+                    response_serializer=SharingService__pb2.Entities.SerializeToString,
+            ),
+            'getListOfSharedUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.getListOfSharedUsers,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.SharedOwners.SerializeToString,
+            ),
+            'getListOfDirectlySharedUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.getListOfDirectlySharedUsers,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.SharedOwners.SerializeToString,
+            ),
+            'getListOfSharedGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getListOfSharedGroups,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.SharedOwners.SerializeToString,
+            ),
+            'getListOfDirectlySharedGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getListOfDirectlySharedGroups,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.SharedOwners.SerializeToString,
+            ),
+            'shareEntityWithUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.shareEntityWithUsers,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'shareEntityWithGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.shareEntityWithGroups,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'revokeEntitySharingFromUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.revokeEntitySharingFromUsers,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'revokeEntitySharingFromGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.revokeEntitySharingFromGroups,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+            'userHasAccess': grpc.unary_unary_rpc_method_handler(
+                    servicer.userHasAccess,
+                    request_deserializer=SharingService__pb2.SharingRequest.FromString,
+                    response_serializer=SharingService__pb2.Status.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'org.apache.custos.sharing.management.service.SharingManagementService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class SharingManagementService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def createEntityType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/createEntityType',
+            SharingService__pb2.EntityTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateEntityType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/updateEntityType',
+            SharingService__pb2.EntityTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteEntityType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/deleteEntityType',
+            SharingService__pb2.EntityTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getEntityType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/getEntityType',
+            SharingService__pb2.EntityTypeRequest.SerializeToString,
+            SharingService__pb2.EntityType.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getEntityTypes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/getEntityTypes',
+            SharingService__pb2.SearchRequest.SerializeToString,
+            SharingService__pb2.EntityTypes.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def createPermissionType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/createPermissionType',
+            SharingService__pb2.PermissionTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updatePermissionType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/updatePermissionType',
+            SharingService__pb2.PermissionTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deletePermissionType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/deletePermissionType',
+            SharingService__pb2.PermissionTypeRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getPermissionType(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/getPermissionType',
+            SharingService__pb2.PermissionTypeRequest.SerializeToString,
+            SharingService__pb2.PermissionType.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getPermissionTypes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/getPermissionTypes',
+            SharingService__pb2.SearchRequest.SerializeToString,
+            SharingService__pb2.PermissionTypes.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def createEntity(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/createEntity',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateEntity(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/updateEntity',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isEntityExists(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/isEntityExists',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getEntity(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/getEntity',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Entity.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteEntity(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/deleteEntity',
+            SharingService__pb2.EntityRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def searchEntities(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/searchEntities',
+            SharingService__pb2.SearchRequest.SerializeToString,
+            SharingService__pb2.Entities.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getListOfSharedUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/getListOfSharedUsers',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.SharedOwners.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getListOfDirectlySharedUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/getListOfDirectlySharedUsers',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.SharedOwners.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getListOfSharedGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/getListOfSharedGroups',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.SharedOwners.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getListOfDirectlySharedGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/getListOfDirectlySharedGroups',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.SharedOwners.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def shareEntityWithUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/shareEntityWithUsers',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def shareEntityWithGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/shareEntityWithGroups',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def revokeEntitySharingFromUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/revokeEntitySharingFromUsers',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def revokeEntitySharingFromGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/revokeEntitySharingFromGroups',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def userHasAccess(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.sharing.management.service.SharingManagementService/userHasAccess',
+            SharingService__pb2.SharingRequest.SerializeToString,
+            SharingService__pb2.Status.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/TenantManagementService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/TenantManagementService_pb2.py
new file mode 100644
index 0000000..d7d890a
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/TenantManagementService_pb2.py
@@ -0,0 +1,870 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: TenantManagementService.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
+import custos.server.core.TenantProfileService_pb2 as TenantProfileService__pb2
+from google.rpc import error_details_pb2 as google_dot_rpc_dot_error__details__pb2
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+import custos.server.core.IamAdminService_pb2 as IamAdminService__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='TenantManagementService.proto',
+  package='org.apache.custos.tenant.management.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n\x1dTenantManagementService.proto\x12+org.apache.custos.tenant.management.service\x1a\x1cgoogle/api/annotations.proto\x1a\x1aTenantProfileService.proto\x1a\x1egoogle/rpc/error_details.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x15IamAdminService.proto\"\xe7\x01\n\x14\x43reateTenantResponse\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x15\n\rclient_secret\x18\x02 \x01(\t\x12\x14\n\x0cis_activated\x18\x03 \x01(\x08\x12\x1b\n\x13\x63lient_id_issued_at\x18\x04 \x01(\x01\x12 \n\x18\x63lient_secret_expires_at\x18\x05 \x01(\x01\x12\x1f\n\x17registration_client_uri\x18\x06 \x01(\t\x12\"\n\x1atoken_endpoint_auth_method\x18\x11 \x01(\t\x12\x0b\n\x03msg\x18\x07 \x01(\t\"\xf7\x04\n\x11GetTenantResponse\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x13\n\x0b\x63lient_name\x18\x02 \x01(\t\x12\x17\n\x0frequester_email\x18\x03 \x01(\t\x12\x18\n\x10\x61\x64min_first_name\x18\x04 \x01(\t\x12\x17\n\x0f\x61\x64min_last_name\x18\x05 \x01(\t\x12\x13\n\x0b\x61\x64min_email\x18\x06 \x01(\t\x12\x10\n\x08\x63ontacts\x18\x07 \x03(\t\x12\x15\n\rredirect_uris\x18\x08 \x03(\t\x12\x13\n\x0bgrant_types\x18\t \x03(\t\x12\x1b\n\x13\x63lient_id_issued_at\x18\n \x01(\x01\x12\x12\n\nclient_uri\x18\x0b \x01(\t\x12\r\n\x05scope\x18\x0c \x01(\t\x12\x0e\n\x06\x64omain\x18\r \x01(\t\x12\x0f\n\x07\x63omment\x18\x0e \x01(\t\x12\x10\n\x08logo_uri\x18\x0f \x01(\t\x12\x18\n\x10\x61pplication_type\x18\x10 \x01(\t\x12\x10\n\x08jwks_uri\x18\x11 \x01(\t\x12#\n\x1b\x65xample_extension_parameter\x18\x12 \x01(\t\x12\x0f\n\x07tos_uri\x18\x13 \x01(\t\x12\x12\n\npolicy_uri\x18\x14 \x01(\t\x12V\n\x04jwks\x18\x15 \x03(\x0b\x32H.org.apache.custos.tenant.management.service.GetTenantResponse.JwksEntry\x12\x13\n\x0bsoftware_id\x18\x16 \x01(\t\x12\x18\n\x10software_version\x18\x17 \x01(\t\x1a+\n\tJwksEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xc9\x01\n\x10GetTenantRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12@\n\x06tenant\x18\x04 \x01(\x0b\x32\x30.org.apache.custos.tenant.profile.service.Tenant\x12M\n\x0b\x63redentials\x18\x05 \x01(\x0b\x32\x38.org.apache.custos.tenant.management.service.Credentials\"\x80\x02\n\x0b\x43redentials\x12\x15\n\riam_client_id\x18\x01 \x01(\t\x12\x19\n\x11iam_client_secret\x18\x02 \x01(\t\x12\x1a\n\x12\x63i_logon_client_id\x18\x03 \x01(\t\x12\x1e\n\x16\x63i_logon_client_secret\x18\x04 \x01(\t\x12\x18\n\x10\x63ustos_client_id\x18\x05 \x01(\t\x12\x1c\n\x14\x63ustos_client_secret\x18\x06 \x01(\t\x12\"\n\x1a\x63ustos_client_id_issued_at\x18\x07 \x01(\x01\x12\'\n\x1f\x63ustos_client_secret_expired_at\x18\x08 \x01(\x01\"\xca\x01\n\x13UpdateTenantRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12M\n\x0b\x63redentials\x18\x03 \x01(\x0b\x32\x38.org.apache.custos.tenant.management.service.Credentials\x12>\n\x04\x62ody\x18\x04 \x01(\x0b\x32\x30.org.apache.custos.tenant.profile.service.Tenant\"\xca\x01\n\x13\x44\x65leteTenantRequest\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12M\n\x0b\x63redentials\x18\x03 \x01(\x0b\x32\x38.org.apache.custos.tenant.management.service.Credentials\x12>\n\x04\x62ody\x18\x04 \x01(\x0b\x32\x30.org.apache.custos.tenant.profile.service.Tenant\")\n\x15GetCredentialsRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\"|\n\x16GetCredentialsResponse\x12\x13\n\x0biamClientId\x18\x01 \x01(\t\x12\x17\n\x0fiamClientSecret\x18\x02 \x01(\t\x12\x17\n\x0f\x63iLogonClientId\x18\x03 \x01(\t\x12\x1b\n\x13\x63iLogonClientSecret\x18\x04 \x01(\t2\xef\x13\n\x17TenantManagementService\x12\xb4\x01\n\x0c\x63reateTenant\x12\x30.org.apache.custos.tenant.profile.service.Tenant\x1a\x41.org.apache.custos.tenant.management.service.CreateTenantResponse\"/\x82\xd3\xe4\x93\x02)\"\'/tenant-management/v1.0.0/oauth2/tenant\x12\xbb\x01\n\tgetTenant\x12=.org.apache.custos.tenant.management.service.GetTenantRequest\x1a>.org.apache.custos.tenant.management.service.GetTenantResponse\"/\x82\xd3\xe4\x93\x02)\x12\'/tenant-management/v1.0.0/oauth2/tenant\x12\xc7\x01\n\x0cupdateTenant\x12@.org.apache.custos.tenant.management.service.UpdateTenantRequest\x1a>.org.apache.custos.tenant.management.service.GetTenantResponse\"5\x82\xd3\xe4\x93\x02/\x1a\'/tenant-management/v1.0.0/oauth2/tenant:\x04\x62ody\x12\x99\x01\n\x0c\x64\x65leteTenant\x12@.org.apache.custos.tenant.management.service.DeleteTenantRequest\x1a\x16.google.protobuf.Empty\"/\x82\xd3\xe4\x93\x02)*\'/tenant-management/v1.0.0/oauth2/tenant\x12\x92\x01\n\x0e\x61\x64\x64TenantRoles\x12..org.apache.custos.iam.service.AddRolesRequest\x1a\'.org.apache.custos.iam.service.AllRoles\"\'\x82\xd3\xe4\x93\x02!\"\x1f/tenant-management/v1.0.0/roles\x12\xaf\x01\n\x11\x61\x64\x64ProtocolMapper\x12\x37.org.apache.custos.iam.service.AddProtocolMapperRequest\x1a..org.apache.custos.iam.service.OperationStatus\"1\x82\xd3\xe4\x93\x02+\")/tenant-management/v1.0.0/protocol/mapper\x12\xad\x01\n\x19\x63onfigureEventPersistence\x12\x36.org.apache.custos.iam.service.EventPersistenceRequest\x1a..org.apache.custos.iam.service.OperationStatus\"(\x82\xd3\xe4\x93\x02\"\" /tenant-management/v1.0.0/events\x12\xbd\x01\n\x12updateTenantStatus\x12=.org.apache.custos.tenant.profile.service.UpdateStatusRequest\x1a>.org.apache.custos.tenant.profile.service.UpdateStatusResponse\"(\x82\xd3\xe4\x93\x02\"\" /tenant-management/v1.0.0/status\x12\xb8\x01\n\rgetAllTenants\x12;.org.apache.custos.tenant.profile.service.GetTenantsRequest\x1a?.org.apache.custos.tenant.profile.service.GetAllTenantsResponse\")\x82\xd3\xe4\x93\x02#\x12!/tenant-management/v1.0.0/tenants\x12\xc0\x01\n\x0fgetChildTenants\x12;.org.apache.custos.tenant.profile.service.GetTenantsRequest\x1a?.org.apache.custos.tenant.profile.service.GetAllTenantsResponse\"/\x82\xd3\xe4\x93\x02)\x12\'/tenant-management/v1.0.0/child/tenants\x12\xe1\x01\n\x14getAllTenantsForUser\x12\x45.org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest\x1a\x46.org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse\":\x82\xd3\xe4\x93\x02\x34\x12\x32/tenant-management/v1.0.0/tenants/{requesterEmail}\x12\xe9\x01\n\x1fgetTenantStatusUpdateAuditTrail\x12>.org.apache.custos.tenant.profile.service.GetAuditTrailRequest\x1aK.org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse\"9\x82\xd3\xe4\x93\x02\x33\x12\x31/tenant-management/v1.0.0/audit/status/{tenantId}\x12\xf3\x01\n\"getTenantAttributeUpdateAuditTrail\x12>.org.apache.custos.tenant.profile.service.GetAuditTrailRequest\x1aN.org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse\"=\x82\xd3\xe4\x93\x02\x37\x12\x35/tenant-management/v1.0.0/audit/attributes/{tenantId}B\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,TenantProfileService__pb2.DESCRIPTOR,google_dot_rpc_dot_error__details__pb2.DESCRIPTOR,google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,IamAdminService__pb2.DESCRIPTOR,])
+
+
+
+
+_CREATETENANTRESPONSE = _descriptor.Descriptor(
+  name='CreateTenantResponse',
+  full_name='org.apache.custos.tenant.management.service.CreateTenantResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.tenant.management.service.CreateTenantResponse.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_secret', full_name='org.apache.custos.tenant.management.service.CreateTenantResponse.client_secret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='is_activated', full_name='org.apache.custos.tenant.management.service.CreateTenantResponse.is_activated', index=2,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_id_issued_at', full_name='org.apache.custos.tenant.management.service.CreateTenantResponse.client_id_issued_at', index=3,
+      number=4, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_secret_expires_at', full_name='org.apache.custos.tenant.management.service.CreateTenantResponse.client_secret_expires_at', index=4,
+      number=5, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='registration_client_uri', full_name='org.apache.custos.tenant.management.service.CreateTenantResponse.registration_client_uri', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='token_endpoint_auth_method', full_name='org.apache.custos.tenant.management.service.CreateTenantResponse.token_endpoint_auth_method', index=6,
+      number=17, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='msg', full_name='org.apache.custos.tenant.management.service.CreateTenantResponse.msg', index=7,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=221,
+  serialized_end=452,
+)
+
+
+_GETTENANTRESPONSE_JWKSENTRY = _descriptor.Descriptor(
+  name='JwksEntry',
+  full_name='org.apache.custos.tenant.management.service.GetTenantResponse.JwksEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.JwksEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.JwksEntry.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=b'8\001',
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1043,
+  serialized_end=1086,
+)
+
+_GETTENANTRESPONSE = _descriptor.Descriptor(
+  name='GetTenantResponse',
+  full_name='org.apache.custos.tenant.management.service.GetTenantResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_name', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.client_name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='requester_email', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.requester_email', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='admin_first_name', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.admin_first_name', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='admin_last_name', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.admin_last_name', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='admin_email', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.admin_email', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='contacts', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.contacts', index=6,
+      number=7, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='redirect_uris', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.redirect_uris', index=7,
+      number=8, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='grant_types', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.grant_types', index=8,
+      number=9, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_id_issued_at', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.client_id_issued_at', index=9,
+      number=10, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='client_uri', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.client_uri', index=10,
+      number=11, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.scope', index=11,
+      number=12, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='domain', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.domain', index=12,
+      number=13, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='comment', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.comment', index=13,
+      number=14, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='logo_uri', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.logo_uri', index=14,
+      number=15, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='application_type', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.application_type', index=15,
+      number=16, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='jwks_uri', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.jwks_uri', index=16,
+      number=17, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='example_extension_parameter', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.example_extension_parameter', index=17,
+      number=18, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tos_uri', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.tos_uri', index=18,
+      number=19, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='policy_uri', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.policy_uri', index=19,
+      number=20, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='jwks', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.jwks', index=20,
+      number=21, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='software_id', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.software_id', index=21,
+      number=22, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='software_version', full_name='org.apache.custos.tenant.management.service.GetTenantResponse.software_version', index=22,
+      number=23, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[_GETTENANTRESPONSE_JWKSENTRY, ],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=455,
+  serialized_end=1086,
+)
+
+
+_GETTENANTREQUEST = _descriptor.Descriptor(
+  name='GetTenantRequest',
+  full_name='org.apache.custos.tenant.management.service.GetTenantRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.tenant.management.service.GetTenantRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.tenant.management.service.GetTenantRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenant', full_name='org.apache.custos.tenant.management.service.GetTenantRequest.tenant', index=2,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='credentials', full_name='org.apache.custos.tenant.management.service.GetTenantRequest.credentials', index=3,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1089,
+  serialized_end=1290,
+)
+
+
+_CREDENTIALS = _descriptor.Descriptor(
+  name='Credentials',
+  full_name='org.apache.custos.tenant.management.service.Credentials',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='iam_client_id', full_name='org.apache.custos.tenant.management.service.Credentials.iam_client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='iam_client_secret', full_name='org.apache.custos.tenant.management.service.Credentials.iam_client_secret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='ci_logon_client_id', full_name='org.apache.custos.tenant.management.service.Credentials.ci_logon_client_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='ci_logon_client_secret', full_name='org.apache.custos.tenant.management.service.Credentials.ci_logon_client_secret', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='custos_client_id', full_name='org.apache.custos.tenant.management.service.Credentials.custos_client_id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='custos_client_secret', full_name='org.apache.custos.tenant.management.service.Credentials.custos_client_secret', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='custos_client_id_issued_at', full_name='org.apache.custos.tenant.management.service.Credentials.custos_client_id_issued_at', index=6,
+      number=7, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='custos_client_secret_expired_at', full_name='org.apache.custos.tenant.management.service.Credentials.custos_client_secret_expired_at', index=7,
+      number=8, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1293,
+  serialized_end=1549,
+)
+
+
+_UPDATETENANTREQUEST = _descriptor.Descriptor(
+  name='UpdateTenantRequest',
+  full_name='org.apache.custos.tenant.management.service.UpdateTenantRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.tenant.management.service.UpdateTenantRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.tenant.management.service.UpdateTenantRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='credentials', full_name='org.apache.custos.tenant.management.service.UpdateTenantRequest.credentials', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='body', full_name='org.apache.custos.tenant.management.service.UpdateTenantRequest.body', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1552,
+  serialized_end=1754,
+)
+
+
+_DELETETENANTREQUEST = _descriptor.Descriptor(
+  name='DeleteTenantRequest',
+  full_name='org.apache.custos.tenant.management.service.DeleteTenantRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.tenant.management.service.DeleteTenantRequest.client_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.tenant.management.service.DeleteTenantRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='credentials', full_name='org.apache.custos.tenant.management.service.DeleteTenantRequest.credentials', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='body', full_name='org.apache.custos.tenant.management.service.DeleteTenantRequest.body', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1757,
+  serialized_end=1959,
+)
+
+
+_GETCREDENTIALSREQUEST = _descriptor.Descriptor(
+  name='GetCredentialsRequest',
+  full_name='org.apache.custos.tenant.management.service.GetCredentialsRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.tenant.management.service.GetCredentialsRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1961,
+  serialized_end=2002,
+)
+
+
+_GETCREDENTIALSRESPONSE = _descriptor.Descriptor(
+  name='GetCredentialsResponse',
+  full_name='org.apache.custos.tenant.management.service.GetCredentialsResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='iamClientId', full_name='org.apache.custos.tenant.management.service.GetCredentialsResponse.iamClientId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='iamClientSecret', full_name='org.apache.custos.tenant.management.service.GetCredentialsResponse.iamClientSecret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='ciLogonClientId', full_name='org.apache.custos.tenant.management.service.GetCredentialsResponse.ciLogonClientId', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='ciLogonClientSecret', full_name='org.apache.custos.tenant.management.service.GetCredentialsResponse.ciLogonClientSecret', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2004,
+  serialized_end=2128,
+)
+
+_GETTENANTRESPONSE_JWKSENTRY.containing_type = _GETTENANTRESPONSE
+_GETTENANTRESPONSE.fields_by_name['jwks'].message_type = _GETTENANTRESPONSE_JWKSENTRY
+_GETTENANTREQUEST.fields_by_name['tenant'].message_type = TenantProfileService__pb2._TENANT
+_GETTENANTREQUEST.fields_by_name['credentials'].message_type = _CREDENTIALS
+_UPDATETENANTREQUEST.fields_by_name['credentials'].message_type = _CREDENTIALS
+_UPDATETENANTREQUEST.fields_by_name['body'].message_type = TenantProfileService__pb2._TENANT
+_DELETETENANTREQUEST.fields_by_name['credentials'].message_type = _CREDENTIALS
+_DELETETENANTREQUEST.fields_by_name['body'].message_type = TenantProfileService__pb2._TENANT
+DESCRIPTOR.message_types_by_name['CreateTenantResponse'] = _CREATETENANTRESPONSE
+DESCRIPTOR.message_types_by_name['GetTenantResponse'] = _GETTENANTRESPONSE
+DESCRIPTOR.message_types_by_name['GetTenantRequest'] = _GETTENANTREQUEST
+DESCRIPTOR.message_types_by_name['Credentials'] = _CREDENTIALS
+DESCRIPTOR.message_types_by_name['UpdateTenantRequest'] = _UPDATETENANTREQUEST
+DESCRIPTOR.message_types_by_name['DeleteTenantRequest'] = _DELETETENANTREQUEST
+DESCRIPTOR.message_types_by_name['GetCredentialsRequest'] = _GETCREDENTIALSREQUEST
+DESCRIPTOR.message_types_by_name['GetCredentialsResponse'] = _GETCREDENTIALSRESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+CreateTenantResponse = _reflection.GeneratedProtocolMessageType('CreateTenantResponse', (_message.Message,), {
+  'DESCRIPTOR' : _CREATETENANTRESPONSE,
+  '__module__' : 'TenantManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.management.service.CreateTenantResponse)
+  })
+_sym_db.RegisterMessage(CreateTenantResponse)
+
+GetTenantResponse = _reflection.GeneratedProtocolMessageType('GetTenantResponse', (_message.Message,), {
+
+  'JwksEntry' : _reflection.GeneratedProtocolMessageType('JwksEntry', (_message.Message,), {
+    'DESCRIPTOR' : _GETTENANTRESPONSE_JWKSENTRY,
+    '__module__' : 'TenantManagementService_pb2'
+    # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.management.service.GetTenantResponse.JwksEntry)
+    })
+  ,
+  'DESCRIPTOR' : _GETTENANTRESPONSE,
+  '__module__' : 'TenantManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.management.service.GetTenantResponse)
+  })
+_sym_db.RegisterMessage(GetTenantResponse)
+_sym_db.RegisterMessage(GetTenantResponse.JwksEntry)
+
+GetTenantRequest = _reflection.GeneratedProtocolMessageType('GetTenantRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETTENANTREQUEST,
+  '__module__' : 'TenantManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.management.service.GetTenantRequest)
+  })
+_sym_db.RegisterMessage(GetTenantRequest)
+
+Credentials = _reflection.GeneratedProtocolMessageType('Credentials', (_message.Message,), {
+  'DESCRIPTOR' : _CREDENTIALS,
+  '__module__' : 'TenantManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.management.service.Credentials)
+  })
+_sym_db.RegisterMessage(Credentials)
+
+UpdateTenantRequest = _reflection.GeneratedProtocolMessageType('UpdateTenantRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATETENANTREQUEST,
+  '__module__' : 'TenantManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.management.service.UpdateTenantRequest)
+  })
+_sym_db.RegisterMessage(UpdateTenantRequest)
+
+DeleteTenantRequest = _reflection.GeneratedProtocolMessageType('DeleteTenantRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETETENANTREQUEST,
+  '__module__' : 'TenantManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.management.service.DeleteTenantRequest)
+  })
+_sym_db.RegisterMessage(DeleteTenantRequest)
+
+GetCredentialsRequest = _reflection.GeneratedProtocolMessageType('GetCredentialsRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETCREDENTIALSREQUEST,
+  '__module__' : 'TenantManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.management.service.GetCredentialsRequest)
+  })
+_sym_db.RegisterMessage(GetCredentialsRequest)
+
+GetCredentialsResponse = _reflection.GeneratedProtocolMessageType('GetCredentialsResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETCREDENTIALSRESPONSE,
+  '__module__' : 'TenantManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.tenant.management.service.GetCredentialsResponse)
+  })
+_sym_db.RegisterMessage(GetCredentialsResponse)
+
+
+DESCRIPTOR._options = None
+_GETTENANTRESPONSE_JWKSENTRY._options = None
+
+_TENANTMANAGEMENTSERVICE = _descriptor.ServiceDescriptor(
+  name='TenantManagementService',
+  full_name='org.apache.custos.tenant.management.service.TenantManagementService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=2131,
+  serialized_end=4674,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='createTenant',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.createTenant',
+    index=0,
+    containing_service=None,
+    input_type=TenantProfileService__pb2._TENANT,
+    output_type=_CREATETENANTRESPONSE,
+    serialized_options=b'\202\323\344\223\002)\"\'/tenant-management/v1.0.0/oauth2/tenant',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getTenant',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.getTenant',
+    index=1,
+    containing_service=None,
+    input_type=_GETTENANTREQUEST,
+    output_type=_GETTENANTRESPONSE,
+    serialized_options=b'\202\323\344\223\002)\022\'/tenant-management/v1.0.0/oauth2/tenant',
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateTenant',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.updateTenant',
+    index=2,
+    containing_service=None,
+    input_type=_UPDATETENANTREQUEST,
+    output_type=_GETTENANTRESPONSE,
+    serialized_options=b'\202\323\344\223\002/\032\'/tenant-management/v1.0.0/oauth2/tenant:\004body',
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteTenant',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.deleteTenant',
+    index=3,
+    containing_service=None,
+    input_type=_DELETETENANTREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=b'\202\323\344\223\002)*\'/tenant-management/v1.0.0/oauth2/tenant',
+  ),
+  _descriptor.MethodDescriptor(
+    name='addTenantRoles',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.addTenantRoles',
+    index=4,
+    containing_service=None,
+    input_type=IamAdminService__pb2._ADDROLESREQUEST,
+    output_type=IamAdminService__pb2._ALLROLES,
+    serialized_options=b'\202\323\344\223\002!\"\037/tenant-management/v1.0.0/roles',
+  ),
+  _descriptor.MethodDescriptor(
+    name='addProtocolMapper',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.addProtocolMapper',
+    index=5,
+    containing_service=None,
+    input_type=IamAdminService__pb2._ADDPROTOCOLMAPPERREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002+\")/tenant-management/v1.0.0/protocol/mapper',
+  ),
+  _descriptor.MethodDescriptor(
+    name='configureEventPersistence',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.configureEventPersistence',
+    index=6,
+    containing_service=None,
+    input_type=IamAdminService__pb2._EVENTPERSISTENCEREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002\"\" /tenant-management/v1.0.0/events',
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateTenantStatus',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.updateTenantStatus',
+    index=7,
+    containing_service=None,
+    input_type=TenantProfileService__pb2._UPDATESTATUSREQUEST,
+    output_type=TenantProfileService__pb2._UPDATESTATUSRESPONSE,
+    serialized_options=b'\202\323\344\223\002\"\" /tenant-management/v1.0.0/status',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllTenants',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.getAllTenants',
+    index=8,
+    containing_service=None,
+    input_type=TenantProfileService__pb2._GETTENANTSREQUEST,
+    output_type=TenantProfileService__pb2._GETALLTENANTSRESPONSE,
+    serialized_options=b'\202\323\344\223\002#\022!/tenant-management/v1.0.0/tenants',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getChildTenants',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.getChildTenants',
+    index=9,
+    containing_service=None,
+    input_type=TenantProfileService__pb2._GETTENANTSREQUEST,
+    output_type=TenantProfileService__pb2._GETALLTENANTSRESPONSE,
+    serialized_options=b'\202\323\344\223\002)\022\'/tenant-management/v1.0.0/child/tenants',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllTenantsForUser',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.getAllTenantsForUser',
+    index=10,
+    containing_service=None,
+    input_type=TenantProfileService__pb2._GETALLTENANTSFORUSERREQUEST,
+    output_type=TenantProfileService__pb2._GETALLTENANTSFORUSERRESPONSE,
+    serialized_options=b'\202\323\344\223\0024\0222/tenant-management/v1.0.0/tenants/{requesterEmail}',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getTenantStatusUpdateAuditTrail',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.getTenantStatusUpdateAuditTrail',
+    index=11,
+    containing_service=None,
+    input_type=TenantProfileService__pb2._GETAUDITTRAILREQUEST,
+    output_type=TenantProfileService__pb2._GETSTATUSUPDATEAUDITTRAILRESPONSE,
+    serialized_options=b'\202\323\344\223\0023\0221/tenant-management/v1.0.0/audit/status/{tenantId}',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getTenantAttributeUpdateAuditTrail',
+    full_name='org.apache.custos.tenant.management.service.TenantManagementService.getTenantAttributeUpdateAuditTrail',
+    index=12,
+    containing_service=None,
+    input_type=TenantProfileService__pb2._GETAUDITTRAILREQUEST,
+    output_type=TenantProfileService__pb2._GETATTRIBUTEUPDATEAUDITTRAILRESPONSE,
+    serialized_options=b'\202\323\344\223\0027\0225/tenant-management/v1.0.0/audit/attributes/{tenantId}',
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_TENANTMANAGEMENTSERVICE)
+
+DESCRIPTOR.services_by_name['TenantManagementService'] = _TENANTMANAGEMENTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/TenantManagementService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/TenantManagementService_pb2_grpc.py
new file mode 100644
index 0000000..9d85f5a
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/TenantManagementService_pb2_grpc.py
@@ -0,0 +1,253 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import custos.server.core.IamAdminService_pb2 as IamAdminService__pb2
+import custos.server.integration.TenantManagementService_pb2 as TenantManagementService__pb2
+import custos.server.core.TenantProfileService_pb2 as TenantProfileService__pb2
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+
+
+class TenantManagementServiceStub(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.createTenant = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/createTenant',
+        request_serializer=TenantProfileService__pb2.Tenant.SerializeToString,
+        response_deserializer=TenantManagementService__pb2.CreateTenantResponse.FromString,
+        )
+    self.getTenant = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/getTenant',
+        request_serializer=TenantManagementService__pb2.GetTenantRequest.SerializeToString,
+        response_deserializer=TenantManagementService__pb2.GetTenantResponse.FromString,
+        )
+    self.updateTenant = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/updateTenant',
+        request_serializer=TenantManagementService__pb2.UpdateTenantRequest.SerializeToString,
+        response_deserializer=TenantManagementService__pb2.GetTenantResponse.FromString,
+        )
+    self.deleteTenant = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/deleteTenant',
+        request_serializer=TenantManagementService__pb2.DeleteTenantRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+        )
+    self.addTenantRoles = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/addTenantRoles',
+        request_serializer=IamAdminService__pb2.AddRolesRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.AllRoles.FromString,
+        )
+    self.addProtocolMapper = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/addProtocolMapper',
+        request_serializer=IamAdminService__pb2.AddProtocolMapperRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.configureEventPersistence = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/configureEventPersistence',
+        request_serializer=IamAdminService__pb2.EventPersistenceRequest.SerializeToString,
+        response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+        )
+    self.updateTenantStatus = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/updateTenantStatus',
+        request_serializer=TenantProfileService__pb2.UpdateStatusRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.UpdateStatusResponse.FromString,
+        )
+    self.getAllTenants = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/getAllTenants',
+        request_serializer=TenantProfileService__pb2.GetTenantsRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetAllTenantsResponse.FromString,
+        )
+    self.getChildTenants = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/getChildTenants',
+        request_serializer=TenantProfileService__pb2.GetTenantsRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetAllTenantsResponse.FromString,
+        )
+    self.getAllTenantsForUser = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/getAllTenantsForUser',
+        request_serializer=TenantProfileService__pb2.GetAllTenantsForUserRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetAllTenantsForUserResponse.FromString,
+        )
+    self.getTenantStatusUpdateAuditTrail = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/getTenantStatusUpdateAuditTrail',
+        request_serializer=TenantProfileService__pb2.GetAuditTrailRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetStatusUpdateAuditTrailResponse.FromString,
+        )
+    self.getTenantAttributeUpdateAuditTrail = channel.unary_unary(
+        '/org.apache.custos.tenant.management.service.TenantManagementService/getTenantAttributeUpdateAuditTrail',
+        request_serializer=TenantProfileService__pb2.GetAuditTrailRequest.SerializeToString,
+        response_deserializer=TenantProfileService__pb2.GetAttributeUpdateAuditTrailResponse.FromString,
+        )
+
+
+class TenantManagementServiceServicer(object):
+  # missing associated documentation comment in .proto file
+  pass
+
+  def createTenant(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getTenant(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def updateTenant(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteTenant(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def addTenantRoles(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def addProtocolMapper(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def configureEventPersistence(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def updateTenantStatus(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAllTenants(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getChildTenants(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getAllTenantsForUser(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getTenantStatusUpdateAuditTrail(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getTenantAttributeUpdateAuditTrail(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_TenantManagementServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'createTenant': grpc.unary_unary_rpc_method_handler(
+          servicer.createTenant,
+          request_deserializer=TenantProfileService__pb2.Tenant.FromString,
+          response_serializer=TenantManagementService__pb2.CreateTenantResponse.SerializeToString,
+      ),
+      'getTenant': grpc.unary_unary_rpc_method_handler(
+          servicer.getTenant,
+          request_deserializer=TenantManagementService__pb2.GetTenantRequest.FromString,
+          response_serializer=TenantManagementService__pb2.GetTenantResponse.SerializeToString,
+      ),
+      'updateTenant': grpc.unary_unary_rpc_method_handler(
+          servicer.updateTenant,
+          request_deserializer=TenantManagementService__pb2.UpdateTenantRequest.FromString,
+          response_serializer=TenantManagementService__pb2.GetTenantResponse.SerializeToString,
+      ),
+      'deleteTenant': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteTenant,
+          request_deserializer=TenantManagementService__pb2.DeleteTenantRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+      ),
+      'addTenantRoles': grpc.unary_unary_rpc_method_handler(
+          servicer.addTenantRoles,
+          request_deserializer=IamAdminService__pb2.AddRolesRequest.FromString,
+          response_serializer=IamAdminService__pb2.AllRoles.SerializeToString,
+      ),
+      'addProtocolMapper': grpc.unary_unary_rpc_method_handler(
+          servicer.addProtocolMapper,
+          request_deserializer=IamAdminService__pb2.AddProtocolMapperRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'configureEventPersistence': grpc.unary_unary_rpc_method_handler(
+          servicer.configureEventPersistence,
+          request_deserializer=IamAdminService__pb2.EventPersistenceRequest.FromString,
+          response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+      ),
+      'updateTenantStatus': grpc.unary_unary_rpc_method_handler(
+          servicer.updateTenantStatus,
+          request_deserializer=TenantProfileService__pb2.UpdateStatusRequest.FromString,
+          response_serializer=TenantProfileService__pb2.UpdateStatusResponse.SerializeToString,
+      ),
+      'getAllTenants': grpc.unary_unary_rpc_method_handler(
+          servicer.getAllTenants,
+          request_deserializer=TenantProfileService__pb2.GetTenantsRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetAllTenantsResponse.SerializeToString,
+      ),
+      'getChildTenants': grpc.unary_unary_rpc_method_handler(
+          servicer.getChildTenants,
+          request_deserializer=TenantProfileService__pb2.GetTenantsRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetAllTenantsResponse.SerializeToString,
+      ),
+      'getAllTenantsForUser': grpc.unary_unary_rpc_method_handler(
+          servicer.getAllTenantsForUser,
+          request_deserializer=TenantProfileService__pb2.GetAllTenantsForUserRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetAllTenantsForUserResponse.SerializeToString,
+      ),
+      'getTenantStatusUpdateAuditTrail': grpc.unary_unary_rpc_method_handler(
+          servicer.getTenantStatusUpdateAuditTrail,
+          request_deserializer=TenantProfileService__pb2.GetAuditTrailRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetStatusUpdateAuditTrailResponse.SerializeToString,
+      ),
+      'getTenantAttributeUpdateAuditTrail': grpc.unary_unary_rpc_method_handler(
+          servicer.getTenantAttributeUpdateAuditTrail,
+          request_deserializer=TenantProfileService__pb2.GetAuditTrailRequest.FromString,
+          response_serializer=TenantProfileService__pb2.GetAttributeUpdateAuditTrailResponse.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.custos.tenant.management.service.TenantManagementService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/UserManagementService_pb2.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/UserManagementService_pb2.py
new file mode 100644
index 0000000..9724a49
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/UserManagementService_pb2.py
@@ -0,0 +1,746 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: UserManagementService.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
+import custos.server.core.UserProfileService_pb2 as UserProfileService__pb2
+import custos.server.core.IamAdminService_pb2 as IamAdminService__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='UserManagementService.proto',
+  package='org.apache.custos.user.management.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x1bUserManagementService.proto\x12)org.apache.custos.user.management.service\x1a\x1cgoogle/api/annotations.proto\x1a\x18UserProfileService.proto\x1a\x15IamAdminService.proto\"\xc3\x01\n\x12UserProfileRequest\x12I\n\x0cuser_profile\x18\x01 \x01(\x0b\x32\x33.org.apache.custos.user.profile.service.UserProfile\x12\x10\n\x08\x63lientId\x18\x02 \x01(\t\x12\x10\n\x08tenantId\x18\x03 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x04 \x01(\t\x12\x14\n\x0c\x63lientSecret\x18\x05 \x01(\t\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\"o\n\x0eGetUserRequest\x12\x10\n\x08username\x18\x01 \x01(\t\x12K\n\x11userSearchRequest\x18\x02 \x01(\x0b\x32\x30.org.apache.custos.iam.service.UserSearchRequest\"\xa1\x01\n\x0fGetUsersRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x0e\n\x06offset\x18\x04 \x01(\x05\x12\r\n\x05limit\x18\x05 \x01(\x05\x12\x0e\n\x06search\x18\x06 \x01(\t\x12\x13\n\x0biamClientId\x18\x07 \x01(\t\x12\x17\n\x0fiamClientSecret\x18\x08 \x01(\t\"\x88\x01\n\rResetPassword\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x13\n\x0biamClientId\x18\x05 \x01(\t\x12\x17\n\x0fiamClientSecret\x18\x06 \x01(\t\"j\n\x14ResetPasswordRequest\x12R\n\x10passwordMetadata\x18\x01 \x01(\x0b\x32\x38.org.apache.custos.user.management.service.ResetPassword\"\xd3\x01\n\x16LinkUserProfileRequest\x12\x18\n\x10\x63urrent_username\x18\x01 \x01(\t\x12\x19\n\x11previous_username\x18\x02 \x01(\t\x12\x1a\n\x12linking_attributes\x18\x03 \x03(\t\x12\x10\n\x08tenantId\x18\x04 \x01(\x03\x12\x13\n\x0biamClientId\x18\x05 \x01(\t\x12\x17\n\x0fiamClientSecret\x18\x06 \x01(\t\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x07 \x01(\t\x12\x13\n\x0bperformedBy\x18\x08 \x01(\t\">\n\x18SynchronizeUserDBRequest\x12\x10\n\x08tenantId\x18\x02 \x01(\x03\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t2\xeb\x1f\n\x15UserManagementService\x12\xa3\x01\n\x0cregisterUser\x12\x32.org.apache.custos.iam.service.RegisterUserRequest\x1a\x33.org.apache.custos.iam.service.RegisterUserResponse\"*\x82\xd3\xe4\x93\x02$\"\x1c/user-management/v1.0.0/user:\x04user\x12\xb1\x01\n\x16registerAndEnableUsers\x12\x33.org.apache.custos.iam.service.RegisterUsersRequest\x1a\x34.org.apache.custos.iam.service.RegisterUsersResponse\",\x82\xd3\xe4\x93\x02&\"\x1d/user-management/v1.0.0/users:\x05users\x12\xa8\x01\n\x11\x61\x64\x64UserAttributes\x12\x37.org.apache.custos.iam.service.AddUserAttributesRequest\x1a..org.apache.custos.iam.service.OperationStatus\"*\x82\xd3\xe4\x93\x02$\"\"/user-management/v1.0.0/attributes\x12\xad\x01\n\x14\x64\x65leteUserAttributes\x12\x39.org.apache.custos.iam.service.DeleteUserAttributeRequest\x1a..org.apache.custos.iam.service.OperationStatus\"*\x82\xd3\xe4\x93\x02$*\"/user-management/v1.0.0/attributes\x12\xa8\x01\n\nenableUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a\x31.org.apache.custos.iam.service.UserRepresentation\"5\x82\xd3\xe4\x93\x02/\"\'/user-management/v1.0.0/user/activation:\x04user\x12\xab\x01\n\x0b\x64isableUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a\x31.org.apache.custos.iam.service.UserRepresentation\"7\x82\xd3\xe4\x93\x02\x31\")/user-management/v1.0.0/user/deactivation:\x04user\x12\xaa\x01\n\x14grantAdminPrivileges\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\"0\x82\xd3\xe4\x93\x02*\"\"/user-management/v1.0.0/user/admin:\x04user\x12\xab\x01\n\x15removeAdminPrivileges\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\"0\x82\xd3\xe4\x93\x02**\"/user-management/v1.0.0/user/admin:\x04user\x12\xa2\x01\n\x0f\x61\x64\x64RolesToUsers\x12\x32.org.apache.custos.iam.service.AddUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\"+\x82\xd3\xe4\x93\x02%\"#/user-management/v1.0.0/users/roles\x12\xa9\x01\n\risUserEnabled\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\"6\x82\xd3\xe4\x93\x02\x30\x12./user-management/v1.0.0/user/activation/status\x12\xaa\x01\n\x13isUsernameAvailable\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\"1\x82\xd3\xe4\x93\x02+\x12)/user-management/v1.0.0/user/availability\x12\x94\x01\n\x07getUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a\x31.org.apache.custos.iam.service.UserRepresentation\"$\x82\xd3\xe4\x93\x02\x1e\x12\x1c/user-management/v1.0.0/user\x12\x95\x01\n\tfindUsers\x12/.org.apache.custos.iam.service.FindUsersRequest\x1a\x30.org.apache.custos.iam.service.FindUsersResponse\"%\x82\xd3\xe4\x93\x02\x1f\x12\x1d/user-management/v1.0.0/users\x12\xa0\x01\n\rresetPassword\x12\x30.org.apache.custos.iam.service.ResetUserPassword\x1a..org.apache.custos.iam.service.OperationStatus\"-\x82\xd3\xe4\x93\x02\'\x1a%/user-management/v1.0.0/user/password\x12\x9a\x01\n\ndeleteUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\"*\x82\xd3\xe4\x93\x02$*\x1c/user-management/v1.0.0/user:\x04user\x12\xa4\x01\n\x0f\x64\x65leteUserRoles\x12\x35.org.apache.custos.iam.service.DeleteUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\"*\x82\xd3\xe4\x93\x02$*\"/user-management/v1.0.0/user/roles\x12\xc3\x01\n\x11updateUserProfile\x12=.org.apache.custos.user.management.service.UserProfileRequest\x1a\x33.org.apache.custos.user.profile.service.UserProfile\":\x82\xd3\xe4\x93\x02\x34\x1a$/user-management/v1.0.0/user/profile:\x0cuser_profile\x12\xb2\x01\n\x0egetUserProfile\x12=.org.apache.custos.user.management.service.UserProfileRequest\x1a\x33.org.apache.custos.user.profile.service.UserProfile\",\x82\xd3\xe4\x93\x02&\x12$/user-management/v1.0.0/user/profile\x12\xb5\x01\n\x11\x64\x65leteUserProfile\x12=.org.apache.custos.user.management.service.UserProfileRequest\x1a\x33.org.apache.custos.user.profile.service.UserProfile\",\x82\xd3\xe4\x93\x02&*$/user-management/v1.0.0/user/profile\x12\xce\x01\n\x1agetAllUserProfilesInTenant\x12=.org.apache.custos.user.management.service.UserProfileRequest\x1a\x42.org.apache.custos.user.profile.service.GetAllUserProfilesResponse\"-\x82\xd3\xe4\x93\x02\'\x12%/user-management/v1.0.0/users/profile\x12\xb9\x01\n\x0flinkUserProfile\x12\x41.org.apache.custos.user.management.service.LinkUserProfileRequest\x1a..org.apache.custos.iam.service.OperationStatus\"3\x82\xd3\xe4\x93\x02-\"+/user-management/v1.0.0/user/profile/mapper\x12\xd8\x01\n\x19getUserProfileAuditTrails\x12\x42.org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest\x1a\x43.org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse\"2\x82\xd3\xe4\x93\x02,\x12*/user-management/v1.0.0/user/profile/audit\x12\xb9\x01\n\x12synchronizeUserDBs\x12\x43.org.apache.custos.user.management.service.SynchronizeUserDBRequest\x1a..org.apache.custos.iam.service.OperationStatus\".\x82\xd3\xe4\x93\x02(\"&/user-management/v1.0.0/db/synchronizeB\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,UserProfileService__pb2.DESCRIPTOR,IamAdminService__pb2.DESCRIPTOR,])
+
+
+
+
+_USERPROFILEREQUEST = _descriptor.Descriptor(
+  name='UserProfileRequest',
+  full_name='org.apache.custos.user.management.service.UserProfileRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='user_profile', full_name='org.apache.custos.user.management.service.UserProfileRequest.user_profile', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.user.management.service.UserProfileRequest.clientId', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.management.service.UserProfileRequest.tenantId', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.user.management.service.UserProfileRequest.accessToken', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSecret', full_name='org.apache.custos.user.management.service.UserProfileRequest.clientSecret', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.user.management.service.UserProfileRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=154,
+  serialized_end=349,
+)
+
+
+_GETUSERREQUEST = _descriptor.Descriptor(
+  name='GetUserRequest',
+  full_name='org.apache.custos.user.management.service.GetUserRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.user.management.service.GetUserRequest.username', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='userSearchRequest', full_name='org.apache.custos.user.management.service.GetUserRequest.userSearchRequest', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=351,
+  serialized_end=462,
+)
+
+
+_GETUSERSREQUEST = _descriptor.Descriptor(
+  name='GetUsersRequest',
+  full_name='org.apache.custos.user.management.service.GetUsersRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.management.service.GetUsersRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='email', full_name='org.apache.custos.user.management.service.GetUsersRequest.email', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.user.management.service.GetUsersRequest.username', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='offset', full_name='org.apache.custos.user.management.service.GetUsersRequest.offset', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='limit', full_name='org.apache.custos.user.management.service.GetUsersRequest.limit', index=4,
+      number=5, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='search', full_name='org.apache.custos.user.management.service.GetUsersRequest.search', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='iamClientId', full_name='org.apache.custos.user.management.service.GetUsersRequest.iamClientId', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='iamClientSecret', full_name='org.apache.custos.user.management.service.GetUsersRequest.iamClientSecret', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=465,
+  serialized_end=626,
+)
+
+
+_RESETPASSWORD = _descriptor.Descriptor(
+  name='ResetPassword',
+  full_name='org.apache.custos.user.management.service.ResetPassword',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.management.service.ResetPassword.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.user.management.service.ResetPassword.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.user.management.service.ResetPassword.username', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='password', full_name='org.apache.custos.user.management.service.ResetPassword.password', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='iamClientId', full_name='org.apache.custos.user.management.service.ResetPassword.iamClientId', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='iamClientSecret', full_name='org.apache.custos.user.management.service.ResetPassword.iamClientSecret', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=629,
+  serialized_end=765,
+)
+
+
+_RESETPASSWORDREQUEST = _descriptor.Descriptor(
+  name='ResetPasswordRequest',
+  full_name='org.apache.custos.user.management.service.ResetPasswordRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='passwordMetadata', full_name='org.apache.custos.user.management.service.ResetPasswordRequest.passwordMetadata', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=767,
+  serialized_end=873,
+)
+
+
+_LINKUSERPROFILEREQUEST = _descriptor.Descriptor(
+  name='LinkUserProfileRequest',
+  full_name='org.apache.custos.user.management.service.LinkUserProfileRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='current_username', full_name='org.apache.custos.user.management.service.LinkUserProfileRequest.current_username', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='previous_username', full_name='org.apache.custos.user.management.service.LinkUserProfileRequest.previous_username', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='linking_attributes', full_name='org.apache.custos.user.management.service.LinkUserProfileRequest.linking_attributes', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.management.service.LinkUserProfileRequest.tenantId', index=3,
+      number=4, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='iamClientId', full_name='org.apache.custos.user.management.service.LinkUserProfileRequest.iamClientId', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='iamClientSecret', full_name='org.apache.custos.user.management.service.LinkUserProfileRequest.iamClientSecret', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.user.management.service.LinkUserProfileRequest.accessToken', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.user.management.service.LinkUserProfileRequest.performedBy', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=876,
+  serialized_end=1087,
+)
+
+
+_SYNCHRONIZEUSERDBREQUEST = _descriptor.Descriptor(
+  name='SynchronizeUserDBRequest',
+  full_name='org.apache.custos.user.management.service.SynchronizeUserDBRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.user.management.service.SynchronizeUserDBRequest.tenantId', index=0,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.user.management.service.SynchronizeUserDBRequest.clientId', index=1,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1089,
+  serialized_end=1151,
+)
+
+_USERPROFILEREQUEST.fields_by_name['user_profile'].message_type = UserProfileService__pb2._USERPROFILE
+_GETUSERREQUEST.fields_by_name['userSearchRequest'].message_type = IamAdminService__pb2._USERSEARCHREQUEST
+_RESETPASSWORDREQUEST.fields_by_name['passwordMetadata'].message_type = _RESETPASSWORD
+DESCRIPTOR.message_types_by_name['UserProfileRequest'] = _USERPROFILEREQUEST
+DESCRIPTOR.message_types_by_name['GetUserRequest'] = _GETUSERREQUEST
+DESCRIPTOR.message_types_by_name['GetUsersRequest'] = _GETUSERSREQUEST
+DESCRIPTOR.message_types_by_name['ResetPassword'] = _RESETPASSWORD
+DESCRIPTOR.message_types_by_name['ResetPasswordRequest'] = _RESETPASSWORDREQUEST
+DESCRIPTOR.message_types_by_name['LinkUserProfileRequest'] = _LINKUSERPROFILEREQUEST
+DESCRIPTOR.message_types_by_name['SynchronizeUserDBRequest'] = _SYNCHRONIZEUSERDBREQUEST
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+UserProfileRequest = _reflection.GeneratedProtocolMessageType('UserProfileRequest', (_message.Message,), {
+  'DESCRIPTOR' : _USERPROFILEREQUEST,
+  '__module__' : 'UserManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.management.service.UserProfileRequest)
+  })
+_sym_db.RegisterMessage(UserProfileRequest)
+
+GetUserRequest = _reflection.GeneratedProtocolMessageType('GetUserRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETUSERREQUEST,
+  '__module__' : 'UserManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.management.service.GetUserRequest)
+  })
+_sym_db.RegisterMessage(GetUserRequest)
+
+GetUsersRequest = _reflection.GeneratedProtocolMessageType('GetUsersRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETUSERSREQUEST,
+  '__module__' : 'UserManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.management.service.GetUsersRequest)
+  })
+_sym_db.RegisterMessage(GetUsersRequest)
+
+ResetPassword = _reflection.GeneratedProtocolMessageType('ResetPassword', (_message.Message,), {
+  'DESCRIPTOR' : _RESETPASSWORD,
+  '__module__' : 'UserManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.management.service.ResetPassword)
+  })
+_sym_db.RegisterMessage(ResetPassword)
+
+ResetPasswordRequest = _reflection.GeneratedProtocolMessageType('ResetPasswordRequest', (_message.Message,), {
+  'DESCRIPTOR' : _RESETPASSWORDREQUEST,
+  '__module__' : 'UserManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.management.service.ResetPasswordRequest)
+  })
+_sym_db.RegisterMessage(ResetPasswordRequest)
+
+LinkUserProfileRequest = _reflection.GeneratedProtocolMessageType('LinkUserProfileRequest', (_message.Message,), {
+  'DESCRIPTOR' : _LINKUSERPROFILEREQUEST,
+  '__module__' : 'UserManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.management.service.LinkUserProfileRequest)
+  })
+_sym_db.RegisterMessage(LinkUserProfileRequest)
+
+SynchronizeUserDBRequest = _reflection.GeneratedProtocolMessageType('SynchronizeUserDBRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SYNCHRONIZEUSERDBREQUEST,
+  '__module__' : 'UserManagementService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.user.management.service.SynchronizeUserDBRequest)
+  })
+_sym_db.RegisterMessage(SynchronizeUserDBRequest)
+
+
+DESCRIPTOR._options = None
+
+_USERMANAGEMENTSERVICE = _descriptor.ServiceDescriptor(
+  name='UserManagementService',
+  full_name='org.apache.custos.user.management.service.UserManagementService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=1154,
+  serialized_end=5229,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='registerUser',
+    full_name='org.apache.custos.user.management.service.UserManagementService.registerUser',
+    index=0,
+    containing_service=None,
+    input_type=IamAdminService__pb2._REGISTERUSERREQUEST,
+    output_type=IamAdminService__pb2._REGISTERUSERRESPONSE,
+    serialized_options=b'\202\323\344\223\002$\"\034/user-management/v1.0.0/user:\004user',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='registerAndEnableUsers',
+    full_name='org.apache.custos.user.management.service.UserManagementService.registerAndEnableUsers',
+    index=1,
+    containing_service=None,
+    input_type=IamAdminService__pb2._REGISTERUSERSREQUEST,
+    output_type=IamAdminService__pb2._REGISTERUSERSRESPONSE,
+    serialized_options=b'\202\323\344\223\002&\"\035/user-management/v1.0.0/users:\005users',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addUserAttributes',
+    full_name='org.apache.custos.user.management.service.UserManagementService.addUserAttributes',
+    index=2,
+    containing_service=None,
+    input_type=IamAdminService__pb2._ADDUSERATTRIBUTESREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002$\"\"/user-management/v1.0.0/attributes',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteUserAttributes',
+    full_name='org.apache.custos.user.management.service.UserManagementService.deleteUserAttributes',
+    index=3,
+    containing_service=None,
+    input_type=IamAdminService__pb2._DELETEUSERATTRIBUTEREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002$*\"/user-management/v1.0.0/attributes',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='enableUser',
+    full_name='org.apache.custos.user.management.service.UserManagementService.enableUser',
+    index=4,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERSEARCHREQUEST,
+    output_type=IamAdminService__pb2._USERREPRESENTATION,
+    serialized_options=b'\202\323\344\223\002/\"\'/user-management/v1.0.0/user/activation:\004user',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='disableUser',
+    full_name='org.apache.custos.user.management.service.UserManagementService.disableUser',
+    index=5,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERSEARCHREQUEST,
+    output_type=IamAdminService__pb2._USERREPRESENTATION,
+    serialized_options=b'\202\323\344\223\0021\")/user-management/v1.0.0/user/deactivation:\004user',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='grantAdminPrivileges',
+    full_name='org.apache.custos.user.management.service.UserManagementService.grantAdminPrivileges',
+    index=6,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERSEARCHREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002*\"\"/user-management/v1.0.0/user/admin:\004user',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeAdminPrivileges',
+    full_name='org.apache.custos.user.management.service.UserManagementService.removeAdminPrivileges',
+    index=7,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERSEARCHREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002**\"/user-management/v1.0.0/user/admin:\004user',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addRolesToUsers',
+    full_name='org.apache.custos.user.management.service.UserManagementService.addRolesToUsers',
+    index=8,
+    containing_service=None,
+    input_type=IamAdminService__pb2._ADDUSERROLESREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002%\"#/user-management/v1.0.0/users/roles',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isUserEnabled',
+    full_name='org.apache.custos.user.management.service.UserManagementService.isUserEnabled',
+    index=9,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERSEARCHREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\0020\022./user-management/v1.0.0/user/activation/status',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isUsernameAvailable',
+    full_name='org.apache.custos.user.management.service.UserManagementService.isUsernameAvailable',
+    index=10,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERSEARCHREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002+\022)/user-management/v1.0.0/user/availability',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUser',
+    full_name='org.apache.custos.user.management.service.UserManagementService.getUser',
+    index=11,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERSEARCHREQUEST,
+    output_type=IamAdminService__pb2._USERREPRESENTATION,
+    serialized_options=b'\202\323\344\223\002\036\022\034/user-management/v1.0.0/user',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='findUsers',
+    full_name='org.apache.custos.user.management.service.UserManagementService.findUsers',
+    index=12,
+    containing_service=None,
+    input_type=IamAdminService__pb2._FINDUSERSREQUEST,
+    output_type=IamAdminService__pb2._FINDUSERSRESPONSE,
+    serialized_options=b'\202\323\344\223\002\037\022\035/user-management/v1.0.0/users',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='resetPassword',
+    full_name='org.apache.custos.user.management.service.UserManagementService.resetPassword',
+    index=13,
+    containing_service=None,
+    input_type=IamAdminService__pb2._RESETUSERPASSWORD,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002\'\032%/user-management/v1.0.0/user/password',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteUser',
+    full_name='org.apache.custos.user.management.service.UserManagementService.deleteUser',
+    index=14,
+    containing_service=None,
+    input_type=IamAdminService__pb2._USERSEARCHREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002$*\034/user-management/v1.0.0/user:\004user',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteUserRoles',
+    full_name='org.apache.custos.user.management.service.UserManagementService.deleteUserRoles',
+    index=15,
+    containing_service=None,
+    input_type=IamAdminService__pb2._DELETEUSERROLESREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002$*\"/user-management/v1.0.0/user/roles',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateUserProfile',
+    full_name='org.apache.custos.user.management.service.UserManagementService.updateUserProfile',
+    index=16,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=UserProfileService__pb2._USERPROFILE,
+    serialized_options=b'\202\323\344\223\0024\032$/user-management/v1.0.0/user/profile:\014user_profile',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUserProfile',
+    full_name='org.apache.custos.user.management.service.UserManagementService.getUserProfile',
+    index=17,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=UserProfileService__pb2._USERPROFILE,
+    serialized_options=b'\202\323\344\223\002&\022$/user-management/v1.0.0/user/profile',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteUserProfile',
+    full_name='org.apache.custos.user.management.service.UserManagementService.deleteUserProfile',
+    index=18,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=UserProfileService__pb2._USERPROFILE,
+    serialized_options=b'\202\323\344\223\002&*$/user-management/v1.0.0/user/profile',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllUserProfilesInTenant',
+    full_name='org.apache.custos.user.management.service.UserManagementService.getAllUserProfilesInTenant',
+    index=19,
+    containing_service=None,
+    input_type=_USERPROFILEREQUEST,
+    output_type=UserProfileService__pb2._GETALLUSERPROFILESRESPONSE,
+    serialized_options=b'\202\323\344\223\002\'\022%/user-management/v1.0.0/users/profile',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='linkUserProfile',
+    full_name='org.apache.custos.user.management.service.UserManagementService.linkUserProfile',
+    index=20,
+    containing_service=None,
+    input_type=_LINKUSERPROFILEREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002-\"+/user-management/v1.0.0/user/profile/mapper',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUserProfileAuditTrails',
+    full_name='org.apache.custos.user.management.service.UserManagementService.getUserProfileAuditTrails',
+    index=21,
+    containing_service=None,
+    input_type=UserProfileService__pb2._GETUPDATEAUDITTRAILREQUEST,
+    output_type=UserProfileService__pb2._GETUPDATEAUDITTRAILRESPONSE,
+    serialized_options=b'\202\323\344\223\002,\022*/user-management/v1.0.0/user/profile/audit',
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='synchronizeUserDBs',
+    full_name='org.apache.custos.user.management.service.UserManagementService.synchronizeUserDBs',
+    index=22,
+    containing_service=None,
+    input_type=_SYNCHRONIZEUSERDBREQUEST,
+    output_type=IamAdminService__pb2._OPERATIONSTATUS,
+    serialized_options=b'\202\323\344\223\002(\"&/user-management/v1.0.0/db/synchronize',
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_USERMANAGEMENTSERVICE)
+
+DESCRIPTOR.services_by_name['UserManagementService'] = _USERMANAGEMENTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-client-sdks/custos-python-sdk/custos/server/integration/UserManagementService_pb2_grpc.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/UserManagementService_pb2_grpc.py
new file mode 100644
index 0000000..07d8c70
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/server/integration/UserManagementService_pb2_grpc.py
@@ -0,0 +1,794 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import custos.server.core.IamAdminService_pb2 as IamAdminService__pb2
+import custos.server.integration.UserManagementService_pb2 as UserManagementService__pb2
+import custos.server.core.UserProfileService_pb2 as UserProfileService__pb2
+
+
+class UserManagementServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.registerUser = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/registerUser',
+                request_serializer=IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.RegisterUserResponse.FromString,
+                )
+        self.registerAndEnableUsers = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/registerAndEnableUsers',
+                request_serializer=IamAdminService__pb2.RegisterUsersRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.RegisterUsersResponse.FromString,
+                )
+        self.addUserAttributes = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/addUserAttributes',
+                request_serializer=IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteUserAttributes = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/deleteUserAttributes',
+                request_serializer=IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.enableUser = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/enableUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.UserRepresentation.FromString,
+                )
+        self.disableUser = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/disableUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.UserRepresentation.FromString,
+                )
+        self.grantAdminPrivileges = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/grantAdminPrivileges',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.removeAdminPrivileges = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/removeAdminPrivileges',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.addRolesToUsers = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/addRolesToUsers',
+                request_serializer=IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.isUserEnabled = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/isUserEnabled',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.isUsernameAvailable = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/isUsernameAvailable',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getUser = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/getUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.UserRepresentation.FromString,
+                )
+        self.findUsers = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/findUsers',
+                request_serializer=IamAdminService__pb2.FindUsersRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.FindUsersResponse.FromString,
+                )
+        self.resetPassword = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/resetPassword',
+                request_serializer=IamAdminService__pb2.ResetUserPassword.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteUser = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/deleteUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteUserRoles = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/deleteUserRoles',
+                request_serializer=IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.updateUserProfile = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/updateUserProfile',
+                request_serializer=UserManagementService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.UserProfile.FromString,
+                )
+        self.getUserProfile = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/getUserProfile',
+                request_serializer=UserManagementService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.UserProfile.FromString,
+                )
+        self.deleteUserProfile = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/deleteUserProfile',
+                request_serializer=UserManagementService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.UserProfile.FromString,
+                )
+        self.getAllUserProfilesInTenant = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/getAllUserProfilesInTenant',
+                request_serializer=UserManagementService__pb2.UserProfileRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+                )
+        self.linkUserProfile = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/linkUserProfile',
+                request_serializer=UserManagementService__pb2.LinkUserProfileRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getUserProfileAuditTrails = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/getUserProfileAuditTrails',
+                request_serializer=UserProfileService__pb2.GetUpdateAuditTrailRequest.SerializeToString,
+                response_deserializer=UserProfileService__pb2.GetUpdateAuditTrailResponse.FromString,
+                )
+        self.synchronizeUserDBs = channel.unary_unary(
+                '/org.apache.custos.user.management.service.UserManagementService/synchronizeUserDBs',
+                request_serializer=UserManagementService__pb2.SynchronizeUserDBRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+
+
+class UserManagementServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def registerUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def registerAndEnableUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addUserAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteUserAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def enableUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def disableUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def grantAdminPrivileges(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeAdminPrivileges(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addRolesToUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isUserEnabled(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isUsernameAvailable(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def findUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def resetPassword(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteUserRoles(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllUserProfilesInTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def linkUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getUserProfileAuditTrails(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def synchronizeUserDBs(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_UserManagementServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'registerUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.registerUser,
+                    request_deserializer=IamAdminService__pb2.RegisterUserRequest.FromString,
+                    response_serializer=IamAdminService__pb2.RegisterUserResponse.SerializeToString,
+            ),
+            'registerAndEnableUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.registerAndEnableUsers,
+                    request_deserializer=IamAdminService__pb2.RegisterUsersRequest.FromString,
+                    response_serializer=IamAdminService__pb2.RegisterUsersResponse.SerializeToString,
+            ),
+            'addUserAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.addUserAttributes,
+                    request_deserializer=IamAdminService__pb2.AddUserAttributesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteUserAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteUserAttributes,
+                    request_deserializer=IamAdminService__pb2.DeleteUserAttributeRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'enableUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.enableUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.UserRepresentation.SerializeToString,
+            ),
+            'disableUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.disableUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.UserRepresentation.SerializeToString,
+            ),
+            'grantAdminPrivileges': grpc.unary_unary_rpc_method_handler(
+                    servicer.grantAdminPrivileges,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'removeAdminPrivileges': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeAdminPrivileges,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'addRolesToUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.addRolesToUsers,
+                    request_deserializer=IamAdminService__pb2.AddUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'isUserEnabled': grpc.unary_unary_rpc_method_handler(
+                    servicer.isUserEnabled,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'isUsernameAvailable': grpc.unary_unary_rpc_method_handler(
+                    servicer.isUsernameAvailable,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.getUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.UserRepresentation.SerializeToString,
+            ),
+            'findUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.findUsers,
+                    request_deserializer=IamAdminService__pb2.FindUsersRequest.FromString,
+                    response_serializer=IamAdminService__pb2.FindUsersResponse.SerializeToString,
+            ),
+            'resetPassword': grpc.unary_unary_rpc_method_handler(
+                    servicer.resetPassword,
+                    request_deserializer=IamAdminService__pb2.ResetUserPassword.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteUserRoles': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteUserRoles,
+                    request_deserializer=IamAdminService__pb2.DeleteUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'updateUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateUserProfile,
+                    request_deserializer=UserManagementService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.UserProfile.SerializeToString,
+            ),
+            'getUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.getUserProfile,
+                    request_deserializer=UserManagementService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.UserProfile.SerializeToString,
+            ),
+            'deleteUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteUserProfile,
+                    request_deserializer=UserManagementService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.UserProfile.SerializeToString,
+            ),
+            'getAllUserProfilesInTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllUserProfilesInTenant,
+                    request_deserializer=UserManagementService__pb2.UserProfileRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetAllUserProfilesResponse.SerializeToString,
+            ),
+            'linkUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.linkUserProfile,
+                    request_deserializer=UserManagementService__pb2.LinkUserProfileRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getUserProfileAuditTrails': grpc.unary_unary_rpc_method_handler(
+                    servicer.getUserProfileAuditTrails,
+                    request_deserializer=UserProfileService__pb2.GetUpdateAuditTrailRequest.FromString,
+                    response_serializer=UserProfileService__pb2.GetUpdateAuditTrailResponse.SerializeToString,
+            ),
+            'synchronizeUserDBs': grpc.unary_unary_rpc_method_handler(
+                    servicer.synchronizeUserDBs,
+                    request_deserializer=UserManagementService__pb2.SynchronizeUserDBRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'org.apache.custos.user.management.service.UserManagementService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class UserManagementService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def registerUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/registerUser',
+            IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+            IamAdminService__pb2.RegisterUserResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def registerAndEnableUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/registerAndEnableUsers',
+            IamAdminService__pb2.RegisterUsersRequest.SerializeToString,
+            IamAdminService__pb2.RegisterUsersResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addUserAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/addUserAttributes',
+            IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteUserAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/deleteUserAttributes',
+            IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def enableUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/enableUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.UserRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def disableUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/disableUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.UserRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def grantAdminPrivileges(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/grantAdminPrivileges',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeAdminPrivileges(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/removeAdminPrivileges',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addRolesToUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/addRolesToUsers',
+            IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isUserEnabled(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/isUserEnabled',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isUsernameAvailable(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/isUsernameAvailable',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/getUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.UserRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def findUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/findUsers',
+            IamAdminService__pb2.FindUsersRequest.SerializeToString,
+            IamAdminService__pb2.FindUsersResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def resetPassword(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/resetPassword',
+            IamAdminService__pb2.ResetUserPassword.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/deleteUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteUserRoles(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/deleteUserRoles',
+            IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/updateUserProfile',
+            UserManagementService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.UserProfile.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/getUserProfile',
+            UserManagementService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.UserProfile.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/deleteUserProfile',
+            UserManagementService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.UserProfile.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllUserProfilesInTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/getAllUserProfilesInTenant',
+            UserManagementService__pb2.UserProfileRequest.SerializeToString,
+            UserProfileService__pb2.GetAllUserProfilesResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def linkUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/linkUserProfile',
+            UserManagementService__pb2.LinkUserProfileRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getUserProfileAuditTrails(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/getUserProfileAuditTrails',
+            UserProfileService__pb2.GetUpdateAuditTrailRequest.SerializeToString,
+            UserProfileService__pb2.GetUpdateAuditTrailResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def synchronizeUserDBs(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.user.management.service.UserManagementService/synchronizeUserDBs',
+            UserManagementService__pb2.SynchronizeUserDBRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/custos/server/integration/__init__.py
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/custos/server/integration/__init__.py
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/custos/transport/__init__.py
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/custos/transport/__init__.py
diff --git a/custos-client-sdks/custos-python-sdk/custos/transport/certificate.pem b/custos-client-sdks/custos-python-sdk/custos/transport/certificate.pem
new file mode 100644
index 0000000..d100c07
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/transport/certificate.pem
@@ -0,0 +1,58 @@
+-----BEGIN CERTIFICATE-----
+MIIFWzCCBEOgAwIBAgISA6JzYO6nlLujr8KffuM+R1bIMA0GCSqGSIb3DQEBCwUA
+MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
+ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0yMDA0MjAxOTExNTBaFw0y
+MDA3MTkxOTExNTBaMBwxGjAYBgNVBAMTEWN1c3Rvcy5zY2lnYXAub3JnMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzez05GzyAp0w5P3PLKSAFUetPdSf
+4UIYt8kVo4gsNHxLCSIvAnFRXTABi8QVlGPCA+yI8mGiIm8Aoushr41YYgqizzda
+VpyK+WmrvTuGmxxNlzQ8qZOSpzFZR/5uwsmrwjoLX09yIBP+aUhSvLLBrR+pvKgW
+ndKqH2MzhEEwqCOYhQApnD0BPkbhJvry8WlqqcIN4LQqMotytY6V0/BuhgSvpFIm
+oABGjhfAN+wZgmRqF4QOg9xVVG2T3g21jkqMjS2aErJ9Hzl8MbMXAU+UWvXvMlm+
+fhU/s0esicMYLvaO8APbEbs4vgKqfdl03gnJnJrfqq/epvUixyHFKcioRQIDAQAB
+o4ICZzCCAmMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
+BgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRPEWxxAyd3FxCRODo1+FTK
+mtr5wzAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggrBgEFBQcB
+AQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRzZW5jcnlw
+dC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlw
+dC5vcmcvMBwGA1UdEQQVMBOCEWN1c3Rvcy5zY2lnYXAub3JnMEwGA1UdIARFMEMw
+CAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9j
+cHMubGV0c2VuY3J5cHQub3JnMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHYAsh4F
+zIuizYogTodm+Su5iiUgZ2va+nDnsklTLe+LkF4AAAFxmTfqKwAABAMARzBFAiBy
+fHo+ie26gNq8QImnlDDRmDEddUnW3pC5UPdRGq7negIhAMN/cRVBTbZhtZ5sDQ7t
+/H3etjHgtG65Ns1NdLNiQsbNAHcAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2y
+CJo32RMAAAFxmTfqYQAABAMASDBGAiEAmYJjetlVIiQPfPjuK7v3+f1E4PQJP9OB
+HO+0GLOlbeoCIQCom/22Rf/YMTk289YU7RSjJi3eD3clmJD+n9iDQiZamDANBgkq
+hkiG9w0BAQsFAAOCAQEAg26fuQ9+As87AYCzAGVW12K7BJ7EScnbABPD6XrMWNuG
+EgRpR9l9cnJNxVFzOwRAsrJmo0NpAsSlIIF5ZwqAVE/wwPDYxyeQfExgzNYzikAR
+buvk7q4lmZAaDkgzRlM6avVwYW5/QGiTVc+bx5qk/Y2Wf0UpdaITzqowOHuzx/OL
+BbhMgxxxZwkx4b1Uwpr2eHbeUF/ohQ1LOHpFNuNnefEQVffu05xIOSfea/2if2aB
+EpLC2oIZpgfPnFe9K8yAt3yXCXu5wgexY2sxnWVo4qkVztp9TUqwdv+EOSkoHYDd
+XLHzDL9sItteNw4Q4a6pl7UcvqucNK5twiidzJLMCQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
+SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
+GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
+q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
+SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
+Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
+a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
+/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
+CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
+bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
+c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
+VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
+ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
+MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
+Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
+AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
+uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
+wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
+X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
+PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
+KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
+-----END CERTIFICATE-----
diff --git a/custos-client-sdks/custos-python-sdk/custos/transport/settings.ini b/custos-client-sdks/custos-python-sdk/custos/transport/settings.ini
new file mode 100644
index 0000000..a59a949
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/transport/settings.ini
@@ -0,0 +1,5 @@
+[CustosServer]
+SERVER_HOST = custos.scigap.org
+SERVER_SSL_PORT = 45523
+CLIENT_ID = custos Id
+CLIENT_SEC = custos Sec
\ No newline at end of file
diff --git a/custos-client-sdks/custos-python-sdk/custos/transport/settings.py b/custos-client-sdks/custos-python-sdk/custos/transport/settings.py
new file mode 100644
index 0000000..3cea8ba
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos/transport/settings.py
@@ -0,0 +1,36 @@
+import configparser
+import os
+
+config = configparser.ConfigParser()
+
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+defaultSettings = os.path.join(BASE_DIR, 'transport', 'settings.ini')
+config.read(defaultSettings)
+cert_path = os.path.join(BASE_DIR, 'transport', 'certificate.pem')
+
+
+class CustosServerClientSettings(object):
+
+    def __init__(self, configuration_file_location=None, custos_host=None,
+                 custos_port=None, custos_client_id=None, custos_client_sec=None):
+        if configuration_file_location is not None:
+            config.read(configuration_file_location)
+        self.CUSTOS_CERT_PATH = cert_path
+
+        if custos_host is not None:
+            self.CUSTOS_SERVER_HOST = custos_host
+        else:
+            self.CUSTOS_SERVER_HOST = config.get('CustosServer', 'SERVER_HOST')
+        if custos_port is not None:
+            self.CUSTOS_SERVER_PORT = custos_port
+        else:
+            self.CUSTOS_SERVER_PORT = config.getint('CustosServer', 'SERVER_SSL_PORT')
+        if custos_client_id is not None:
+            self.CUSTOS_CLIENT_ID = custos_client_id
+        else:
+            self.CUSTOS_CLIENT_ID = config.get('CustosServer', 'CLIENT_ID')
+
+        if custos_client_sec is not None:
+            self.CUSTOS_CLIENT_SEC = custos_client_sec
+        else:
+            self.CUSTOS_CLIENT_SEC = config.get('CustosServer', 'CLIENT_SEC')
diff --git a/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/PKG-INFO b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/PKG-INFO
new file mode 100644
index 0000000..f2642f9
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/PKG-INFO
@@ -0,0 +1,10 @@
+Metadata-Version: 1.0
+Name: custos-python-sdk
+Version: 1.0.0
+Summary: Apache Custos Python  SDK
+Home-page: http://custos.com
+Author: Custos Developers
+Author-email: dev@airavata.apache.org
+License: Apache License 2.0
+Description: UNKNOWN
+Platform: UNKNOWN
diff --git a/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/SOURCES.txt b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/SOURCES.txt
new file mode 100644
index 0000000..ae5842d
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/SOURCES.txt
@@ -0,0 +1,69 @@
+README.md
+setup.cfg
+setup.py
+custos/__init__.py
+custos/clients/__init__.py
+custos/clients/agent_management_client.py
+custos/clients/group_management_client.py
+custos/clients/identity_management_client.py
+custos/clients/resource_secret_management_client.py
+custos/clients/sharing_management_client.py
+custos/clients/super_tenant_management_client.py
+custos/clients/tenant_management_client.py
+custos/clients/user_management_client.py
+custos/clients/utils/__init__.py
+custos/clients/utils/certificate_fetching_rest_client.py
+custos/clients/utils/utilities.py
+custos/samples/__init__.py
+custos/samples/agent_management_samples.py
+custos/samples/group_management_samples.py
+custos/samples/identity_management_samples.py
+custos/samples/tenant_management_samples.py
+custos/samples/user_management_samples.py
+custos/samples/resources/__init__.py
+custos/samples/resources/cert.pem
+custos/server/__init__.py
+custos/server/core/AgentProfileService_pb2.py
+custos/server/core/AgentProfileService_pb2_grpc.py
+custos/server/core/ClusterManagementService_pb2.py
+custos/server/core/ClusterManagementService_pb2_grpc.py
+custos/server/core/CredentialStoreService_pb2.py
+custos/server/core/CredentialStoreService_pb2_grpc.py
+custos/server/core/FederatedAuthenticationService_pb2.py
+custos/server/core/FederatedAuthenticationService_pb2_grpc.py
+custos/server/core/IamAdminService_pb2.py
+custos/server/core/IamAdminService_pb2_grpc.py
+custos/server/core/IdentityService_pb2.py
+custos/server/core/IdentityService_pb2_grpc.py
+custos/server/core/ResourceSecretService_pb2.py
+custos/server/core/ResourceSecretService_pb2_grpc.py
+custos/server/core/SharingService_pb2.py
+custos/server/core/SharingService_pb2_grpc.py
+custos/server/core/TenantProfileService_pb2.py
+custos/server/core/TenantProfileService_pb2_grpc.py
+custos/server/core/UserProfileService_pb2.py
+custos/server/core/UserProfileService_pb2_grpc.py
+custos/server/core/__init__.py
+custos/server/integration/AgentManagementService_pb2.py
+custos/server/integration/AgentManagementService_pb2_grpc.py
+custos/server/integration/GroupManagementService_pb2.py
+custos/server/integration/GroupManagementService_pb2_grpc.py
+custos/server/integration/IdentityManagementService_pb2.py
+custos/server/integration/IdentityManagementService_pb2_grpc.py
+custos/server/integration/ResourceSecretManagementService_pb2.py
+custos/server/integration/ResourceSecretManagementService_pb2_grpc.py
+custos/server/integration/SharingManagementService_pb2.py
+custos/server/integration/SharingManagementService_pb2_grpc.py
+custos/server/integration/TenantManagementService_pb2.py
+custos/server/integration/TenantManagementService_pb2_grpc.py
+custos/server/integration/UserManagementService_pb2.py
+custos/server/integration/UserManagementService_pb2_grpc.py
+custos/server/integration/__init__.py
+custos/transport/__init__.py
+custos/transport/certificate.pem
+custos/transport/settings.py
+custos_python_sdk.egg-info/PKG-INFO
+custos_python_sdk.egg-info/SOURCES.txt
+custos_python_sdk.egg-info/dependency_links.txt
+custos_python_sdk.egg-info/requires.txt
+custos_python_sdk.egg-info/top_level.txt
\ No newline at end of file
diff --git a/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/dependency_links.txt b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/requires.txt b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/requires.txt
new file mode 100644
index 0000000..5856210
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/requires.txt
@@ -0,0 +1,10 @@
+google==3.0.0
+protobuf==3.12.2
+google-api-python-client==1.10.0
+googleapis-common-protos==1.52.0
+grpcio==1.30.0
+pyopenssl==19.1.0
+configparser==5.0.0
+requests==2.13.0
+requests-oauthlib==0.7.0
+urllib3==1.25.9
diff --git a/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/top_level.txt b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/top_level.txt
new file mode 100644
index 0000000..ee51cd8
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/custos_python_sdk.egg-info/top_level.txt
@@ -0,0 +1 @@
+custos
diff --git a/custos-client-sdks/custos-python-sdk/requirements.txt b/custos-client-sdks/custos-python-sdk/requirements.txt
new file mode 100644
index 0000000..a23f06d
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/requirements.txt
@@ -0,0 +1,10 @@
+google==3.0.0
+protobuf==3.12.2
+google-api-python-client==1.10.0
+googleapis-common-protos==1.52.0
+grpcio==1.30.0
+pyopenssl==19.1.0
+configparser==5.0.0
+requests==2.13.0
+requests-oauthlib==0.7.0
+urllib3==1.25.9
\ No newline at end of file
diff --git a/custos-samples/samples/__init__.py b/custos-client-sdks/custos-python-sdk/setup.cfg
similarity index 100%
copy from custos-samples/samples/__init__.py
copy to custos-client-sdks/custos-python-sdk/setup.cfg
diff --git a/custos-client-sdks/custos-python-sdk/setup.py b/custos-client-sdks/custos-python-sdk/setup.py
new file mode 100644
index 0000000..da03f6e
--- /dev/null
+++ b/custos-client-sdks/custos-python-sdk/setup.py
@@ -0,0 +1,31 @@
+import os
+
+from setuptools import setup, find_packages
+
+
+def read(fname):
+    with open(os.path.join(os.path.dirname(__file__), fname)) as f:
+        return f.read()
+
+
+setup(
+    name='custos-python-sdk',
+    version='1.0.0',
+    packages=find_packages(),
+    package_data={'': ['*.pem']},
+    include_package_data=True,
+    url='http://custos.com',
+    license='Apache License 2.0',
+    author='Custos Developers',
+    author_email='dev@airavata.apache.org',
+    install_requires=['google==3.0.0', 'protobuf==3.12.2',
+                      'google-api-python-client==1.10.0',
+                      'googleapis-common-protos==1.52.0',
+                      'grpcio==1.30.0',
+                      'pyopenssl==19.1.0',
+                      'configparser==5.0.0',
+                      'requests==2.13.0',
+                      'requests-oauthlib==0.7.0',
+                      'urllib3==1.25.9'],
+    description='Apache Custos Python  SDK'
+)
diff --git a/custos-client-sdks/pom.xml b/custos-client-sdks/pom.xml
new file mode 100644
index 0000000..576c970
--- /dev/null
+++ b/custos-client-sdks/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-client-sdks</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>custos-java-sdk</module>
+        <module>custos-java-clients</module>
+    </modules>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/agent-profile-core-service-client-stub/pom.xml b/custos-core-services-client-stubs/agent-profile-core-service-client-stub/pom.xml
new file mode 100644
index 0000000..ae9e6ab
--- /dev/null
+++ b/custos-core-services-client-stubs/agent-profile-core-service-client-stub/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>agent-profile-core-service-client-stub</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/agent-profile-core-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/agent-profile-core-service-client-stub/src/main/java/org/apache/custos/agent/profile/client/AgentProfileClient.java b/custos-core-services-client-stubs/agent-profile-core-service-client-stub/src/main/java/org/apache/custos/agent/profile/client/AgentProfileClient.java
new file mode 100644
index 0000000..0beb47c
--- /dev/null
+++ b/custos-core-services-client-stubs/agent-profile-core-service-client-stub/src/main/java/org/apache/custos/agent/profile/client/AgentProfileClient.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.client;
+
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.agent.profile.service.Agent;
+import org.apache.custos.agent.profile.service.AgentProfileServiceGrpc;
+import org.apache.custos.agent.profile.service.AgentRequest;
+import org.apache.custos.agent.profile.service.OperationStatus;
+import org.apache.custos.integration.core.ServiceCallback;
+import org.apache.custos.integration.core.ServiceException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class AgentProfileClient {
+
+    private ManagedChannel managedChannel;
+    private AgentProfileServiceGrpc.AgentProfileServiceStub agentProfileServiceStub;
+    private AgentProfileServiceGrpc.AgentProfileServiceBlockingStub agentProfileServiceBlockingStub;
+
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+
+    public AgentProfileClient(List<ClientInterceptor> clientInterceptorList,
+                              @Value("${agent.profile.core.service.dns.name}") String serviceHost,
+                              @Value("${agent.profile.core.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        agentProfileServiceStub = AgentProfileServiceGrpc.newStub(managedChannel);
+        agentProfileServiceBlockingStub = AgentProfileServiceGrpc.newBlockingStub(managedChannel);
+    }
+
+
+    public Agent createAgent(AgentRequest profile) {
+        return agentProfileServiceBlockingStub.createAgent(profile);
+    }
+
+
+    public Agent updateAgent(AgentRequest profile) {
+        return agentProfileServiceBlockingStub.updateAgent(profile);
+    }
+
+
+    public OperationStatus deleteAgent(AgentRequest request) {
+        return agentProfileServiceBlockingStub.deleteAgent(request);
+    }
+
+
+    public Agent getAgent(AgentRequest request) {
+        return agentProfileServiceBlockingStub.getAgent(request);
+    }
+
+
+    private StreamObserver getObserver(ServiceCallback callback, String failureMsg) {
+        final Object[] response = new Object[1];
+        StreamObserver observer = new StreamObserver() {
+            @Override
+            public void onNext(Object o) {
+                response[0] = o;
+            }
+
+            @Override
+            public void onError(Throwable throwable) {
+                callback.onError(new ServiceException(failureMsg, throwable, null));
+            }
+
+            @Override
+            public void onCompleted() {
+                callback.onCompleted(response[0]);
+            }
+        };
+
+        return observer;
+    }
+}
diff --git a/custos-core-services-client-stubs/cluster-management-core-service-client-stub/pom.xml b/custos-core-services-client-stubs/cluster-management-core-service-client-stub/pom.xml
new file mode 100644
index 0000000..f87e49c
--- /dev/null
+++ b/custos-core-services-client-stubs/cluster-management-core-service-client-stub/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>cluster-management-core-service-client-stub</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/cluster-management-core-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/cluster-management-core-service-client-stub/src/main/java/org/apache/custos/cluster/management/client/ClusterManagementClient.java b/custos-core-services-client-stubs/cluster-management-core-service-client-stub/src/main/java/org/apache/custos/cluster/management/client/ClusterManagementClient.java
new file mode 100644
index 0000000..1b772bb
--- /dev/null
+++ b/custos-core-services-client-stubs/cluster-management-core-service-client-stub/src/main/java/org/apache/custos/cluster/management/client/ClusterManagementClient.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.cluster.management.client;
+
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import org.apache.custos.cluster.management.service.ClusterManagementServiceGrpc;
+import org.apache.custos.cluster.management.service.GetServerCertificateRequest;
+import org.apache.custos.cluster.management.service.GetServerCertificateResponse;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class ClusterManagementClient {
+    private ManagedChannel managedChannel;
+    private ClusterManagementServiceGrpc.ClusterManagementServiceStub clusterManagementServiceStub;
+    private ClusterManagementServiceGrpc.ClusterManagementServiceBlockingStub clusterManagementServiceBlockingStub;
+
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+
+    public ClusterManagementClient(List<ClientInterceptor> clientInterceptorList,
+                                   @Value("${cluster.management.core.service.dns.name}") String serviceHost,
+                                   @Value("${cluster.management.core.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        clusterManagementServiceStub = ClusterManagementServiceGrpc.newStub(managedChannel);
+        clusterManagementServiceBlockingStub = ClusterManagementServiceGrpc.newBlockingStub(managedChannel);
+    }
+
+    public GetServerCertificateResponse getCustosServerCertificate(GetServerCertificateRequest request) {
+        return clusterManagementServiceBlockingStub.getCustosServerCertificate(request);
+    }
+
+}
diff --git a/custos-core-services-client-stubs/credential-store-core-service-client-stubs/pom.xml b/custos-core-services-client-stubs/credential-store-core-service-client-stubs/pom.xml
new file mode 100644
index 0000000..5f87654
--- /dev/null
+++ b/custos-core-services-client-stubs/credential-store-core-service-client-stubs/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>credential-store-core-service-client-stubs</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/credential-store-core-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/credential-store-core-service-client-stubs/src/main/java/org/apache/custos/credential/store/client/CredentialStoreServiceClient.java b/custos-core-services-client-stubs/credential-store-core-service-client-stubs/src/main/java/org/apache/custos/credential/store/client/CredentialStoreServiceClient.java
new file mode 100644
index 0000000..5deea14
--- /dev/null
+++ b/custos-core-services-client-stubs/credential-store-core-service-client-stubs/src/main/java/org/apache/custos/credential/store/client/CredentialStoreServiceClient.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.client;
+
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.credential.store.service.*;
+import org.apache.custos.integration.core.ServiceCallback;
+import org.apache.custos.integration.core.ServiceException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * The client class used to connect with credential admin services
+ */
+@Component
+public class CredentialStoreServiceClient {
+
+    private ManagedChannel managedChannel;
+    private CredentialStoreServiceGrpc.CredentialStoreServiceStub credentialStoreServiceStub;
+    private CredentialStoreServiceGrpc.CredentialStoreServiceBlockingStub credentialStoreServiceBlockingStub;
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+
+    public CredentialStoreServiceClient(List<ClientInterceptor> clientInterceptorList,
+                                        @Value("${credential.store.service.dns.name}") String serviceHost,
+                                        @Value("${credential.store.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        credentialStoreServiceStub = CredentialStoreServiceGrpc.newStub(managedChannel);
+        credentialStoreServiceBlockingStub = CredentialStoreServiceGrpc.newBlockingStub(managedChannel);
+    }
+
+    public void putCredentialAsync(CredentialMetadata request, final ServiceCallback callback) {
+        StreamObserver observer = getObserver(callback, " PutCredentialAsync task failed");
+        credentialStoreServiceStub.putCredential(request, observer);
+
+    }
+
+
+    public void getCredentialAsync(GetCredentialRequest request, final ServiceCallback callback) {
+        StreamObserver observer = getObserver(callback, " getCredentialAsync task failed");
+        credentialStoreServiceStub.getCredential(request, observer);
+    }
+
+
+    public void getAllCredentialsAsync(GetAllCredentialsRequest request, final ServiceCallback callback) {
+        StreamObserver observer = getObserver(callback, " getAllCredentialsAsync task failed");
+        credentialStoreServiceStub.getAllCredentials(request, observer);
+    }
+
+
+    public void deleteCredentialAsync(DeleteCredentialRequest request, final ServiceCallback callback) {
+        StreamObserver observer = getObserver(callback, " deleteCredentialAsync task failed");
+        credentialStoreServiceStub.deleteCredential(request, observer);
+    }
+
+    public void getOperationsMetadataAsync(GetOperationsMetadataRequest request, final ServiceCallback callback) {
+        StreamObserver observer = getObserver(callback, "get operations metadata");
+        credentialStoreServiceStub.getOperationMetadata(request, observer);
+    }
+
+
+    public void getNewCustosCredentialsAsync(GetNewCustosCredentialRequest request, final ServiceCallback callback) {
+        StreamObserver observer = getObserver(callback, "get new custos credentials metadata");
+        credentialStoreServiceStub.getNewCustosCredential(request, observer);
+
+    }
+
+
+    public void getOwnerIdFormToken(TokenRequest request, final ServiceCallback callback) {
+        StreamObserver observer = getObserver(callback, "get new custos credentials metadata");
+        credentialStoreServiceStub.getOwnerIdFromToken(request, observer);
+
+    }
+
+
+    public OperationStatus putCredential(CredentialMetadata request) {
+        return credentialStoreServiceBlockingStub.putCredential(request);
+
+    }
+
+
+    public CredentialMetadata getCredential(GetCredentialRequest request) {
+        return credentialStoreServiceBlockingStub.getCredential(request);
+    }
+
+
+    public GetAllCredentialsResponse getAllCredentials(GetAllCredentialsRequest request) {
+        return credentialStoreServiceBlockingStub.getAllCredentials(request);
+    }
+
+
+    public OperationStatus deleteCredential(DeleteCredentialRequest request) {
+        return credentialStoreServiceBlockingStub.deleteCredential(request);
+    }
+
+
+    public GetOperationsMetadataResponse getOperationsMetadata(GetOperationsMetadataRequest request) {
+        return credentialStoreServiceBlockingStub.getOperationMetadata(request);
+    }
+
+    public CredentialMetadata getNewCustosCredentials(GetNewCustosCredentialRequest request) {
+        return credentialStoreServiceBlockingStub.getNewCustosCredential(request);
+    }
+
+    public GetOwnerIdResponse getOwnerIdFormToken(TokenRequest request) {
+        return credentialStoreServiceBlockingStub.getOwnerIdFromToken(request);
+    }
+
+    public CredentialMetadata getCustosCredentialFromToken(TokenRequest request) {
+        return credentialStoreServiceBlockingStub.getCustosCredentialFromToken(request);
+    }
+
+    public CredentialMetadata getCustosCredentialFromClientId(GetCredentialRequest request) {
+        return credentialStoreServiceBlockingStub.getCustosCredentialFromClientId(request);
+    }
+
+    public GetAllCredentialsResponse getAllCredentialFromToken(TokenRequest request) {
+        return credentialStoreServiceBlockingStub.getAllCredentialsFromToken(request);
+    }
+
+    public GetAllCredentialsResponse getAllCredentialsFromJWTToken(TokenRequest request) {
+        return credentialStoreServiceBlockingStub.getAllCredentialsFromJWTToken(request);
+    }
+
+
+    public Credentials getBasicCredentials(TokenRequest request) {
+        return credentialStoreServiceBlockingStub.getBasicCredentials(request);
+    }
+
+    public CredentialMetadata createAgentCredential(CredentialMetadata request) {
+        return credentialStoreServiceBlockingStub.createAgentCredential(request);
+    }
+
+    public CredentialMetadata getAgentCredential(GetCredentialRequest request) {
+        return credentialStoreServiceBlockingStub.getAgentCredential(request);
+    }
+
+    public OperationStatus deleteAgentCredential(CredentialMetadata request) {
+        return credentialStoreServiceBlockingStub.deleteAgentCredential(request);
+    }
+
+    public GetAllCredentialsResponse getCredentialByAgentBasicAuth(TokenRequest request) {
+        return credentialStoreServiceBlockingStub.getCredentialByAgentBasicAuth(request);
+    }
+
+
+
+    private StreamObserver getObserver(ServiceCallback callback, String failureMsg) {
+        final Object[] response = new Object[1];
+        StreamObserver observer = new StreamObserver() {
+            @Override
+            public void onNext(Object o) {
+                response[0] = o;
+            }
+
+            @Override
+            public void onError(Throwable throwable) {
+                callback.onError(new ServiceException(failureMsg, throwable, null));
+            }
+
+            @Override
+            public void onCompleted() {
+                callback.onCompleted(response[0]);
+            }
+        };
+
+        return observer;
+    }
+
+
+}
diff --git a/custos-core-services-client-stubs/custos-logging-client-stub/pom.xml b/custos-core-services-client-stubs/custos-logging-client-stub/pom.xml
new file mode 100644
index 0000000..c66585d
--- /dev/null
+++ b/custos-core-services-client-stubs/custos-logging-client-stub/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-logging-client-stub</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/custos-logging/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/custos-logging-client-stub/src/main/java/org/apache/custos/logging/client/LoggingClient.java b/custos-core-services-client-stubs/custos-logging-client-stub/src/main/java/org/apache/custos/logging/client/LoggingClient.java
new file mode 100644
index 0000000..233f40b
--- /dev/null
+++ b/custos-core-services-client-stubs/custos-logging-client-stub/src/main/java/org/apache/custos/logging/client/LoggingClient.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging.client;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.integration.core.ServiceCallback;
+import org.apache.custos.integration.core.ServiceException;
+import org.apache.custos.logging.service.*;
+import org.apache.custos.logging.service.LogEvent;
+import org.apache.custos.logging.service.LogEvents;
+import org.apache.custos.logging.service.LoggingConfigurationRequest;
+import org.apache.custos.logging.service.LoggingServiceGrpc;
+import org.apache.custos.logging.service.Status;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class LoggingClient {
+    private ManagedChannel managedChannel;
+    private LoggingServiceGrpc.LoggingServiceBlockingStub loggingServiceBlockingStub;
+    private LoggingServiceGrpc.LoggingServiceFutureStub loggingServiceFutureStub;
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+
+    public LoggingClient(List<ClientInterceptor> clientInterceptorList,
+                         @Value("${custos.logging.core.service.dns.name}") String serviceHost,
+                         @Value("${custos.logging.core.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        loggingServiceBlockingStub = LoggingServiceGrpc.newBlockingStub(managedChannel);
+        loggingServiceFutureStub = LoggingServiceGrpc.newFutureStub(managedChannel);
+
+
+    }
+
+
+    public ListenableFuture<org.apache.custos.logging.service.Status> addLogEventAsync(LogEvent logEvent) {
+        return loggingServiceFutureStub.addLogEvent(logEvent);
+    }
+
+    public org.apache.custos.logging.service.Status addLogEvent(LogEvent logEvent) {
+        return loggingServiceBlockingStub.addLogEvent(logEvent);
+    }
+
+    public org.apache.custos.logging.service.Status enable(LoggingConfigurationRequest loggingConfigurationRequest) {
+        return loggingServiceBlockingStub.enable(loggingConfigurationRequest);
+    }
+
+
+    public LogEvents getLogEvents(org.apache.custos.logging.service.LogEventRequest logEventRequest) {
+        return loggingServiceBlockingStub.getLogEvents(logEventRequest);
+    }
+
+    public Status isLogEnabled(LoggingConfigurationRequest loggingConfigurationRequest) {
+        return loggingServiceBlockingStub.isLogEnabled(loggingConfigurationRequest);
+    }
+
+
+    private StreamObserver getObserver(ServiceCallback callback, String failureMsg) {
+        final Object[] response = new Object[1];
+        StreamObserver observer = new StreamObserver() {
+            @Override
+            public void onNext(Object o) {
+                response[0] = o;
+            }
+
+            @Override
+            public void onError(Throwable throwable) {
+                callback.onError(new ServiceException(failureMsg, throwable, null));
+            }
+
+            @Override
+            public void onCompleted() {
+                callback.onCompleted(response[0]);
+            }
+        };
+
+        return observer;
+    }
+}
diff --git a/custos-core-services-client-stubs/federated-authentication-core-service-client-stub/pom.xml b/custos-core-services-client-stubs/federated-authentication-core-service-client-stub/pom.xml
new file mode 100644
index 0000000..0cecb8c
--- /dev/null
+++ b/custos-core-services-client-stubs/federated-authentication-core-service-client-stub/pom.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>federated-authentication-core-service-client-stub</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/federated-authentication-core-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/federated-authentication-core-service-client-stub/src/main/java/org/apache/custos/federated/authentication/client/FederatedAuthenticationClient.java b/custos-core-services-client-stubs/federated-authentication-core-service-client-stub/src/main/java/org/apache/custos/federated/authentication/client/FederatedAuthenticationClient.java
new file mode 100644
index 0000000..e0962d2
--- /dev/null
+++ b/custos-core-services-client-stubs/federated-authentication-core-service-client-stub/src/main/java/org/apache/custos/federated/authentication/client/FederatedAuthenticationClient.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication.client;
+
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.federated.authentication.service.*;
+import org.apache.custos.integration.core.ServiceCallback;
+import org.apache.custos.integration.core.ServiceException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * The client class used to connect IAM admin services
+ */
+@Component
+public class FederatedAuthenticationClient {
+    private ManagedChannel managedChannel;
+    private FederatedAuthenticationServiceGrpc.FederatedAuthenticationServiceStub federatedAuthenticationServiceStub;
+    private FederatedAuthenticationServiceGrpc.FederatedAuthenticationServiceBlockingStub federatedAuthenticationServiceBlockingStub;
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+
+    public FederatedAuthenticationClient(List<ClientInterceptor> clientInterceptorList,
+                                         @Value("${federated.authentication.service.dns.name}") String serviceHost,
+                                         @Value("${federated.authentication.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        federatedAuthenticationServiceStub = FederatedAuthenticationServiceGrpc.newStub(managedChannel);
+        federatedAuthenticationServiceBlockingStub = FederatedAuthenticationServiceGrpc.newBlockingStub(managedChannel);
+    }
+
+
+    public void addClientAsync(ClientMetadata request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "addClient   task failed");
+        federatedAuthenticationServiceStub.addClient(request, observer);
+    }
+
+    public void updateClientAsync(ClientMetadata request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "updateClient   task failed");
+        federatedAuthenticationServiceStub.updateClient(request, observer);
+    }
+
+    public void deleteClientAsync(DeleteClientRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "deleteClient   task failed");
+        federatedAuthenticationServiceStub.deleteClient(request, observer);
+    }
+
+    public void getOperationsMetadataAsync(GetOperationsMetadataRequest request, final ServiceCallback callback) {
+        StreamObserver observer = getObserver(callback, "get operations metadata");
+        federatedAuthenticationServiceStub.getOperationMetadata(request, observer);
+    }
+
+    public void getClientAsync(GetClientRequest request) {
+        federatedAuthenticationServiceBlockingStub.getClient(request);
+    }
+
+    public RegisterClientResponse addClient(ClientMetadata request) {
+        return federatedAuthenticationServiceBlockingStub.addClient(request);
+    }
+
+    public Empty updateClient(ClientMetadata request) {
+        return federatedAuthenticationServiceBlockingStub.updateClient(request);
+    }
+
+    public Empty deleteClient(DeleteClientRequest request) {
+        return federatedAuthenticationServiceBlockingStub.deleteClient(request);
+    }
+
+    public GetClientResponse getClient(GetClientRequest request) {
+        return federatedAuthenticationServiceBlockingStub.getClient(request);
+    }
+
+    public GetOperationsMetadataResponse getOperationsMetadata(GetOperationsMetadataRequest request) {
+        return federatedAuthenticationServiceBlockingStub.getOperationMetadata(request);
+    }
+
+    public Status addToCache(CacheManipulationRequest request) {
+        return federatedAuthenticationServiceBlockingStub.addToCache(request);
+    }
+
+
+    public Status removeFromCache(CacheManipulationRequest request) {
+        return federatedAuthenticationServiceBlockingStub.removeFromCache(request);
+    }
+
+    public GetInstitutionsResponse getFromCache(CacheManipulationRequest request) {
+        return federatedAuthenticationServiceBlockingStub.getFromCache(request);
+    }
+
+    public GetInstitutionsResponse getInstitutions(CacheManipulationRequest request) {
+        return federatedAuthenticationServiceBlockingStub.getInstitutions(request);
+    }
+
+
+    private StreamObserver getObserver(ServiceCallback callback, String failureMsg) {
+        final Object[] response = new Object[1];
+        StreamObserver observer = new StreamObserver() {
+            @Override
+            public void onNext(Object o) {
+                response[0] = o;
+            }
+
+            @Override
+            public void onError(Throwable throwable) {
+                callback.onError(new ServiceException(failureMsg, throwable, null));
+            }
+
+            @Override
+            public void onCompleted() {
+                callback.onCompleted(response[0]);
+            }
+        };
+
+        return observer;
+    }
+
+
+}
diff --git a/custos-core-services-client-stubs/iam-admin-core-service-client-stub/pom.xml b/custos-core-services-client-stubs/iam-admin-core-service-client-stub/pom.xml
new file mode 100644
index 0000000..9899408
--- /dev/null
+++ b/custos-core-services-client-stubs/iam-admin-core-service-client-stub/pom.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>iam-admin-core-service-client-stub</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/iam-admin-core-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/iam-admin-core-service-client-stub/src/main/java/org/apache/custos/iam/admin/client/IamAdminServiceClient.java b/custos-core-services-client-stubs/iam-admin-core-service-client-stub/src/main/java/org/apache/custos/iam/admin/client/IamAdminServiceClient.java
new file mode 100644
index 0000000..e5a820c
--- /dev/null
+++ b/custos-core-services-client-stubs/iam-admin-core-service-client-stub/src/main/java/org/apache/custos/iam/admin/client/IamAdminServiceClient.java
@@ -0,0 +1,380 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.iam.admin.client;
+
+import com.google.protobuf.Empty;
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.integration.core.ServiceCallback;
+import org.apache.custos.integration.core.ServiceException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * The client class used to connect IAM admin services
+ */
+@Component
+public class IamAdminServiceClient {
+    private ManagedChannel managedChannel;
+    private IamAdminServiceGrpc.IamAdminServiceStub iamAdminServiceStub;
+    private IamAdminServiceGrpc.IamAdminServiceBlockingStub iamAdminServiceBlockingStub;
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+    private String iamServerURL;
+
+
+    public IamAdminServiceClient(List<ClientInterceptor> clientInterceptorList,
+                                 @Value("${iam.admin.service.dns.name}") String serviceHost,
+                                 @Value("${iam.admin.service.port}") int servicePort,
+                                 @Value("${iam.server.url}") String url) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        iamAdminServiceStub = IamAdminServiceGrpc.newStub(managedChannel);
+        iamAdminServiceBlockingStub = IamAdminServiceGrpc.newBlockingStub(managedChannel);
+        this.iamServerURL = url;
+    }
+
+
+    public void setUPTenantAsync(SetUpTenantRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "Setup  tenant task failed");
+        iamAdminServiceStub.setUPTenant(request, observer);
+    }
+
+
+    public void isUsernameAvailableAsync(UserSearchRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "isUsernameAvailable task failed");
+        iamAdminServiceStub.isUsernameAvailable(request, observer);
+    }
+
+
+    public void isUserEnabledAsync(UserSearchRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "isUserEnabled task failed");
+        iamAdminServiceStub.isUserEnabled(request, observer);
+    }
+
+
+    public void registerUserAsync(RegisterUserRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "registerUser task failed");
+        iamAdminServiceStub.registerUser(request, observer);
+    }
+
+
+    public void enableUserAsync(UserSearchRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "enableUser task failed");
+        iamAdminServiceStub.enableUser(request, observer);
+    }
+
+
+    public void isUserExistAsync(UserSearchRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "isUserExist task failed");
+        iamAdminServiceStub.isUserExist(request, observer);
+    }
+
+
+    public void getUserAsync(UserSearchRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "getUser task failed");
+        iamAdminServiceStub.getUser(request, observer);
+    }
+
+
+    public void getUsersAsync(FindUsersRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "getUsers task failed");
+        iamAdminServiceStub.findUsers(request, observer);
+    }
+
+
+    public void resetPasswordAsync(ResetUserPassword request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "resetPassword task failed");
+        iamAdminServiceStub.resetPassword(request, observer);
+    }
+
+
+    public void findUsersAsync(FindUsersRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "findUsers task failed");
+        iamAdminServiceStub.findUsers(request, observer);
+    }
+
+
+    public void updateUserProfileAsync(UpdateUserProfileRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "updateUserProfile task failed");
+        iamAdminServiceStub.updateUserProfile(request, observer);
+    }
+
+    public void deleteUserAsync(UserSearchRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "deleteUser task failed");
+        iamAdminServiceStub.deleteUser(request, observer);
+    }
+
+
+    public void deleteRoleFromUserAsync(DeleteUserRolesRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "deleteRoleFromUser task failed");
+        iamAdminServiceStub.deleteRolesFromUser(request, observer);
+    }
+
+    public void getOperationsMetadataAsync(GetOperationsMetadataRequest request, final ServiceCallback callback) {
+        StreamObserver observer = getObserver(callback, "get operations metadata");
+        iamAdminServiceStub.getOperationMetadata(request, observer);
+    }
+
+    public SetUpTenantResponse setUPTenant(SetUpTenantRequest request) {
+        return iamAdminServiceBlockingStub.setUPTenant(request);
+    }
+
+
+    public OperationStatus isUsernameAvailable(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.isUsernameAvailable(request);
+    }
+
+
+    public OperationStatus isUserEnabled(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.isUserEnabled(request);
+    }
+
+
+    public OperationStatus addRolesToUsers(AddUserRolesRequest request) {
+        return iamAdminServiceBlockingStub.addRolesToUsers(request);
+    }
+
+
+    public RegisterUserResponse registerUser(RegisterUserRequest request) {
+        return iamAdminServiceBlockingStub.registerUser(request);
+
+    }
+
+
+    public UserRepresentation enableUser(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.enableUser(request);
+
+    }
+
+    public UserRepresentation disableUser(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.disableUser(request);
+
+    }
+
+
+    public CheckingResponse isUserExist(UserSearchRequest request) {
+
+        return iamAdminServiceBlockingStub.isUserExist(request);
+    }
+
+
+    public UserRepresentation getUser(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.getUser(request);
+
+    }
+
+
+    public FindUsersResponse getUsers(FindUsersRequest request) {
+        return iamAdminServiceBlockingStub.findUsers(request);
+
+    }
+
+
+    public OperationStatus resetPassword(ResetUserPassword request) {
+        return iamAdminServiceBlockingStub.resetPassword(request);
+
+    }
+
+
+    public OperationStatus updateUserProfile(UpdateUserProfileRequest request) {
+        return iamAdminServiceBlockingStub.updateUserProfile(request);
+    }
+
+    public OperationStatus deleteUser(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.deleteUser(request);
+    }
+
+
+    public OperationStatus deleteUserRoles(DeleteUserRolesRequest request) {
+        return iamAdminServiceBlockingStub.deleteRolesFromUser(request);
+    }
+
+    public GetOperationsMetadataResponse getOperationsMetadata(GetOperationsMetadataRequest request) {
+        return iamAdminServiceBlockingStub.getOperationMetadata(request);
+    }
+
+    public FederateIDPResponse configureFederatedIDP(ConfigureFederateIDPRequest request) {
+        return iamAdminServiceBlockingStub.configureFederatedIDP(request);
+    }
+
+
+    public RegisterUsersResponse registerAndEnableUsers(RegisterUsersRequest registerUsersRequest) {
+        return iamAdminServiceBlockingStub.registerAndEnableUsers(registerUsersRequest);
+    }
+
+    public AllRoles addRolesToTenant(AddRolesRequest rolesRequest) {
+        return iamAdminServiceBlockingStub.addRolesToTenant(rolesRequest);
+    }
+
+    public OperationStatus addProtocolMapper(AddProtocolMapperRequest addProtocolMapper) {
+        return iamAdminServiceBlockingStub.addProtocolMapper(addProtocolMapper);
+    }
+
+    public OperationStatus addUserAttributes(AddUserAttributesRequest addUserAttributesRequest) {
+        return iamAdminServiceBlockingStub.addUserAttributes(addUserAttributesRequest);
+    }
+
+    public OperationStatus deleteUserAttributes(DeleteUserAttributeRequest deleteUserAttributeRequest) {
+        return iamAdminServiceBlockingStub.deleteUserAttributes(deleteUserAttributeRequest);
+    }
+
+    public OperationStatus configureEventPersistence(EventPersistenceRequest persistenceRequest) {
+        return iamAdminServiceBlockingStub.configureEventPersistence(persistenceRequest);
+    }
+
+    public GroupsResponse createGroups(GroupsRequest groupsRequest) {
+        return iamAdminServiceBlockingStub.createGroups(groupsRequest);
+    }
+
+    public GroupRepresentation updateGroup(GroupRequest groupsRequest) {
+        return iamAdminServiceBlockingStub.updateGroup(groupsRequest);
+    }
+
+    public OperationStatus deleteGroup(GroupRequest groupsRequest) {
+        return iamAdminServiceBlockingStub.deleteGroup(groupsRequest);
+    }
+
+    public GroupRepresentation findGroup(GroupRequest groupsRequest) {
+        return iamAdminServiceBlockingStub.findGroup(groupsRequest);
+    }
+
+
+    public GroupsResponse getAllGroups(GroupRequest request) {
+        return iamAdminServiceBlockingStub.getAllGroups(request);
+    }
+
+
+    public OperationStatus addUserToGroup(UserGroupMappingRequest request) {
+        return iamAdminServiceBlockingStub.addUserToGroup(request);
+    }
+
+    public OperationStatus removeUserFromGroup(UserGroupMappingRequest request) {
+        return iamAdminServiceBlockingStub.removeUserFromGroup(request);
+    }
+
+    public SetUpTenantResponse createAgentClient(AgentClientMetadata request) {
+        return iamAdminServiceBlockingStub.createAgentClient(request);
+    }
+
+    public OperationStatus configureAgentClient(AgentClientMetadata request) {
+        return iamAdminServiceBlockingStub.configureAgentClient(request);
+    }
+
+    public OperationStatus isAgentNameAvailable(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.isAgentNameAvailable(request);
+    }
+
+    public RegisterUserResponse registerAndEnableAgent(RegisterUserRequest request) {
+        return iamAdminServiceBlockingStub.registerAndEnableAgent(request);
+    }
+
+    public OperationStatus disableAgent(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.disableAgent(request);
+    }
+
+    public OperationStatus deleteAgent(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.deleteAgent(request);
+    }
+
+    public OperationStatus addAgentAttributes(AddUserAttributesRequest request) {
+        return iamAdminServiceBlockingStub.addAgentAttributes(request);
+    }
+
+    public OperationStatus deleteAgentAttributes(DeleteUserAttributeRequest request) {
+        return iamAdminServiceBlockingStub.deleteAgentAttributes(request);
+    }
+
+    public OperationStatus addRolesToAgent(AddUserRolesRequest request) {
+        return iamAdminServiceBlockingStub.addRolesToAgent(request);
+    }
+
+    public OperationStatus deleteAgentRoles(DeleteUserRolesRequest request) {
+        return iamAdminServiceBlockingStub.deleteAgentRoles(request);
+    }
+
+    public OperationStatus enableAgent(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.enableAgent(request);
+    }
+
+    public OperationStatus grantAdminPrivilege(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.grantAdminPrivilege(request);
+    }
+
+    public OperationStatus removeAdminPrivilege(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.removeAdminPrivilege(request);
+    }
+
+    public SetUpTenantResponse updateTenant(SetUpTenantRequest request) {
+        return iamAdminServiceBlockingStub.updateTenant(request);
+    }
+
+    public GetAllResourcesResponse getAllResources(GetAllResources request) {
+        return iamAdminServiceBlockingStub.getAllResources(request);
+    }
+
+    public AllRoles getRolesOfTenant(GetRolesRequest request) {
+        return iamAdminServiceBlockingStub.getRolesOfTenant(request);
+    }
+
+    public Agent getAgent(UserSearchRequest request) {
+        return iamAdminServiceBlockingStub.getAgent(request);
+    }
+
+    public String getIamServerURL() {
+        return iamServerURL;
+    }
+
+
+    public Empty deleteTenant(DeleteTenantRequest request) {
+        return iamAdminServiceBlockingStub.deleteTenant(request);
+    }
+
+    private StreamObserver getObserver(ServiceCallback callback, String failureMsg) {
+        final Object[] response = new Object[1];
+        StreamObserver observer = new StreamObserver() {
+            @Override
+            public void onNext(Object o) {
+                response[0] = o;
+            }
+
+            @Override
+            public void onError(Throwable throwable) {
+                callback.onError(new ServiceException(failureMsg, throwable, null));
+            }
+
+            @Override
+            public void onCompleted() {
+                callback.onCompleted(response[0]);
+            }
+        };
+
+        return observer;
+    }
+
+
+}
diff --git a/custos-core-services-client-stubs/identity-core-service-client-stub/pom.xml b/custos-core-services-client-stubs/identity-core-service-client-stub/pom.xml
new file mode 100644
index 0000000..48452a9
--- /dev/null
+++ b/custos-core-services-client-stubs/identity-core-service-client-stub/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>identity-core-service-client-stub</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/identity-core-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/identity-core-service-client-stub/src/main/java/org/apache/custos/identity/client/IdentityClient.java b/custos-core-services-client-stubs/identity-core-service-client-stub/src/main/java/org/apache/custos/identity/client/IdentityClient.java
new file mode 100644
index 0000000..4a5f670
--- /dev/null
+++ b/custos-core-services-client-stubs/identity-core-service-client-stub/src/main/java/org/apache/custos/identity/client/IdentityClient.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.client;
+
+import com.google.protobuf.Struct;
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.identity.service.*;
+import org.apache.custos.integration.core.ServiceCallback;
+import org.apache.custos.integration.core.ServiceException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * The client class used to connect IAM admin services
+ */
+@Component
+public class IdentityClient {
+    private ManagedChannel managedChannel;
+    private IdentityServiceGrpc.IdentityServiceStub identityServiceStub;
+    private IdentityServiceGrpc.IdentityServiceBlockingStub identityServiceBlockingStub;
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+
+    public IdentityClient(List<ClientInterceptor> clientInterceptorList,
+                          @Value("${identity.service.dns.name}") String serviceHost,
+                          @Value("${identity.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        identityServiceStub = IdentityServiceGrpc.newStub(managedChannel);
+        identityServiceBlockingStub = IdentityServiceGrpc.newBlockingStub(managedChannel);
+    }
+
+
+    public void authenticateAsync(AuthenticationRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "Authenticate task failed");
+        identityServiceStub.authenticate(request, observer);
+    }
+
+
+    public void isAuthenticatedAsync(AuthToken request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "isAuthenticated task failed");
+        identityServiceStub.isAuthenticate(request, observer);
+    }
+
+
+    public void getUserAsync(AuthToken request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "getUser task failed");
+        identityServiceStub.getUser(request, observer);
+    }
+
+
+    public void getUserManagementSATokenRequestAsync(GetUserManagementSATokenRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "GetUserManagementSAToken task failed");
+        identityServiceStub.getUserManagementServiceAccountAccessToken(request, observer);
+    }
+
+    public AuthToken authenticate(AuthenticationRequest request) {
+        return identityServiceBlockingStub.authenticate(request);
+    }
+
+
+    public IsAuthenticateResponse isAuthenticated(AuthToken request) {
+        return identityServiceBlockingStub.isAuthenticate(request);
+    }
+
+
+    public User getUser(AuthToken request) {
+        return identityServiceBlockingStub.getUser(request);
+    }
+
+
+    public AuthToken getUserManagementSATokenRequest(GetUserManagementSATokenRequest request) {
+        return identityServiceBlockingStub.getUserManagementServiceAccountAccessToken(request);
+    }
+
+    public Struct getAccessToken(GetTokenRequest request) {
+        return identityServiceBlockingStub.getToken(request);
+    }
+
+    public AuthorizationResponse getAuthorizationEndpoint(GetAuthorizationEndpointRequest request) {
+        return identityServiceBlockingStub.getAuthorizeEndpoint(request);
+    }
+
+    public Struct getOIDCConfiguration(GetOIDCConfiguration request) {
+        return identityServiceBlockingStub.getOIDCConfiguration(request);
+    }
+
+    public Struct getTokenByPasswordGrantType(GetTokenRequest request) {
+        return identityServiceBlockingStub.getTokenByPasswordGrantType(request);
+    }
+
+
+    public Struct getTokenByRefreshTokenGrantType(GetTokenRequest request) {
+       return identityServiceBlockingStub.getTokenByRefreshTokenGrantType(request);
+    }
+
+    public OperationStatus endSession(EndSessionRequest request) {
+        return identityServiceBlockingStub.endSession(request);
+    }
+    public Struct getJWKS(GetJWKSRequest request) {
+        return identityServiceBlockingStub.getJWKS(request);
+    }
+
+    private StreamObserver getObserver(ServiceCallback callback, String failureMsg) {
+        final Object[] response = new Object[1];
+        StreamObserver observer = new StreamObserver() {
+            @Override
+            public void onNext(Object o) {
+                response[0] = o;
+            }
+
+            @Override
+            public void onError(Throwable throwable) {
+                callback.onError(new ServiceException(failureMsg, throwable, null));
+            }
+
+            @Override
+            public void onCompleted() {
+                callback.onCompleted(response[0]);
+            }
+        };
+
+        return observer;
+    }
+
+
+}
diff --git a/custos-core-services-client-stubs/pom.xml b/custos-core-services-client-stubs/pom.xml
new file mode 100644
index 0000000..4bbecfc
--- /dev/null
+++ b/custos-core-services-client-stubs/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>pom</packaging>
+    <modules>
+        <module>tenant-profile-core-service-client-stub</module>
+        <module>iam-admin-core-service-client-stub</module>
+        <module>credential-store-core-service-client-stubs</module>
+        <module>federated-authentication-core-service-client-stub</module>
+        <module>identity-core-service-client-stub</module>
+        <module>user-profile-core-service-client-stub</module>
+        <module>agent-profile-core-service-client-stub</module>
+        <module>cluster-management-core-service-client-stub</module>
+        <module>resource-secret-core-service-client-stub</module>
+        <module>sharing-core-service-client-stub</module>
+        <module>custos-logging-client-stub</module>
+    </modules>
+    <artifactId>custos-core-services-client-stubs</artifactId>
+
+    
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/resource-secret-core-service-client-stub/pom.xml b/custos-core-services-client-stubs/resource-secret-core-service-client-stub/pom.xml
new file mode 100644
index 0000000..b7d28ff
--- /dev/null
+++ b/custos-core-services-client-stubs/resource-secret-core-service-client-stub/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>resource-secret-core-service-client-stub</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/resource-secret-core-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/resource-secret-core-service-client-stub/src/main/java/org/apache/custos/resource/secret/client/ResourceSecretClient.java b/custos-core-services-client-stubs/resource-secret-core-service-client-stub/src/main/java/org/apache/custos/resource/secret/client/ResourceSecretClient.java
new file mode 100644
index 0000000..1f789fe
--- /dev/null
+++ b/custos-core-services-client-stubs/resource-secret-core-service-client-stub/src/main/java/org/apache/custos/resource/secret/client/ResourceSecretClient.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.client;
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import org.apache.custos.resource.secret.service.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class ResourceSecretClient {
+
+    private ManagedChannel managedChannel;
+    private ResourceSecretServiceGrpc.ResourceSecretServiceBlockingStub resourceSecretServiceBlockingStub;
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+    public ResourceSecretClient(List<ClientInterceptor> clientInterceptorList,
+                                @Value("${resource.secret.service.dns.name}") String serviceHost,
+                                @Value("${resource.secret.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        resourceSecretServiceBlockingStub = ResourceSecretServiceGrpc.newBlockingStub(managedChannel);
+    }
+
+
+    public SecretMetadata getSecretResponse(GetSecretRequest request) {
+        return resourceSecretServiceBlockingStub.getSecret(request);
+
+    }
+
+
+    public SecretMetadata getResourceCredentialSummary(GetResourceCredentialByTokenRequest request) {
+
+        return resourceSecretServiceBlockingStub.getResourceCredentialSummary(request);
+    }
+
+    public ResourceCredentialSummaries getAllResourceCredentialSummaries(GetResourceCredentialSummariesRequest request) {
+        return resourceSecretServiceBlockingStub.getAllResourceCredentialSummaries(request);
+    }
+
+    public AddResourceCredentialResponse addSSHCredential(SSHCredential credential) {
+        return resourceSecretServiceBlockingStub.addSSHCredential(credential);
+    }
+
+    public AddResourceCredentialResponse addPasswordCredential(PasswordCredential credential) {
+        return resourceSecretServiceBlockingStub.addPasswordCredential(credential);
+    }
+
+    public AddResourceCredentialResponse addCertificateCredential(CertificateCredential certificateCredential) {
+        return resourceSecretServiceBlockingStub.addCertificateCredential(certificateCredential);
+    }
+
+    public SSHCredential getSSHCredential(GetResourceCredentialByTokenRequest request) {
+        return resourceSecretServiceBlockingStub.getSSHCredential(request);
+    }
+
+    public PasswordCredential getPasswordCredential(GetResourceCredentialByTokenRequest request) {
+        return resourceSecretServiceBlockingStub.getPasswordCredential(request);
+    }
+
+    public CertificateCredential getCertificateCredential(GetResourceCredentialByTokenRequest request) {
+        return resourceSecretServiceBlockingStub.getCertificateCredential(request);
+    }
+
+    public ResourceCredentialOperationStatus deleteSSHCredential(GetResourceCredentialByTokenRequest request) {
+        return resourceSecretServiceBlockingStub.deleteSSHCredential(request);
+    }
+
+    public ResourceCredentialOperationStatus deletePWDCredential(GetResourceCredentialByTokenRequest request) {
+        return resourceSecretServiceBlockingStub.deletePWDCredential(request);
+    }
+
+    public ResourceCredentialOperationStatus deleteCertificateCredential(GetResourceCredentialByTokenRequest request) {
+        return resourceSecretServiceBlockingStub.deleteCertificateCredential(request);
+    }
+
+
+}
diff --git a/custos-core-services-client-stubs/sharing-core-service-client-stub/pom.xml b/custos-core-services-client-stubs/sharing-core-service-client-stub/pom.xml
new file mode 100644
index 0000000..f0a6c18
--- /dev/null
+++ b/custos-core-services-client-stubs/sharing-core-service-client-stub/pom.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sharing-core-service-client-stub</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/sharing-core-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/sharing-core-service-client-stub/src/main/java/org/apache/custos/sharing/client/SharingClient.java b/custos-core-services-client-stubs/sharing-core-service-client-stub/src/main/java/org/apache/custos/sharing/client/SharingClient.java
new file mode 100644
index 0000000..7226d82
--- /dev/null
+++ b/custos-core-services-client-stubs/sharing-core-service-client-stub/src/main/java/org/apache/custos/sharing/client/SharingClient.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.client;
+
+
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import org.apache.custos.sharing.service.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * Sharing client for sharing core service
+ */
+@Component
+public class SharingClient {
+
+    private ManagedChannel managedChannel;
+    private SharingServiceGrpc.SharingServiceBlockingStub sharingServiceBlockingStub;
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+
+    public SharingClient(List<ClientInterceptor> clientInterceptorList,
+                         @Value("${sharing.core.service.dns.name}") String serviceHost,
+                         @Value("${sharing.core.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        sharingServiceBlockingStub = SharingServiceGrpc.newBlockingStub(managedChannel);
+
+    }
+
+
+    public Status createEntityType(org.apache.custos.sharing.service.EntityTypeRequest request) {
+
+        return sharingServiceBlockingStub.createEntityType(request);
+    }
+
+
+    public Status updateEntityType(org.apache.custos.sharing.service.EntityTypeRequest request) {
+        return sharingServiceBlockingStub.updateEntityType(request);
+    }
+
+    public Status deleteEntityType(org.apache.custos.sharing.service.EntityTypeRequest request) {
+        return sharingServiceBlockingStub.deleteEntityType(request);
+
+    }
+
+
+    public EntityType getEntityType(org.apache.custos.sharing.service.EntityTypeRequest request) {
+        return sharingServiceBlockingStub.getEntityType(request);
+
+    }
+
+
+    public EntityTypes getEntityTypes(org.apache.custos.sharing.service.SearchRequest request) {
+        return sharingServiceBlockingStub.getEntityTypes(request);
+    }
+
+
+    public Status createPermissionType(org.apache.custos.sharing.service.PermissionTypeRequest request) {
+
+        return sharingServiceBlockingStub.createPermissionType(request);
+    }
+
+
+    public Status updatePermissionType(org.apache.custos.sharing.service.PermissionTypeRequest request) {
+        return sharingServiceBlockingStub.updatePermissionType(request);
+    }
+
+
+    public Status deletePermissionType(org.apache.custos.sharing.service.PermissionTypeRequest request) {
+        return sharingServiceBlockingStub.deletePermissionType(request);
+
+    }
+
+
+    public PermissionType getPermissionType(org.apache.custos.sharing.service.PermissionTypeRequest request) {
+
+        return sharingServiceBlockingStub.getPermissionType(request);
+    }
+
+
+    public PermissionTypes getPermissionTypes(org.apache.custos.sharing.service.SearchRequest request) {
+
+        return sharingServiceBlockingStub.getPermissionTypes(request);
+    }
+
+
+    public Status createEntity(org.apache.custos.sharing.service.EntityRequest request) {
+
+        return sharingServiceBlockingStub.createEntity(request);
+    }
+
+
+    public Status updateEntity(org.apache.custos.sharing.service.EntityRequest request) {
+        return sharingServiceBlockingStub.updateEntity(request);
+    }
+
+
+    public Status isEntityExists(org.apache.custos.sharing.service.EntityRequest request) {
+
+        return sharingServiceBlockingStub.isEntityExists(request);
+    }
+
+
+    public Entity getEntity(org.apache.custos.sharing.service.EntityRequest request) {
+        return sharingServiceBlockingStub.getEntity(request);
+    }
+
+
+    public Status deleteEntity(org.apache.custos.sharing.service.EntityRequest request) {
+        return sharingServiceBlockingStub.deleteEntity(request);
+    }
+
+
+    public Entities searchEntities(org.apache.custos.sharing.service.SearchRequest request) {
+
+        return sharingServiceBlockingStub.searchEntities(request);
+    }
+
+
+    public SharedOwners getListOfSharedUsers(org.apache.custos.sharing.service.SharingRequest request) {
+        return sharingServiceBlockingStub.getListOfSharedUsers(request);
+    }
+
+
+    public SharedOwners getListOfDirectlySharedUsers(org.apache.custos.sharing.service.SharingRequest request) {
+        return sharingServiceBlockingStub.getListOfDirectlySharedUsers(request);
+    }
+
+
+    public SharedOwners getListOfSharedGroups(org.apache.custos.sharing.service.SharingRequest request) {
+        return sharingServiceBlockingStub.getListOfSharedGroups(request);
+
+    }
+
+
+    public SharedOwners getListOfDirectlySharedGroups(org.apache.custos.sharing.service.SharingRequest request) {
+        return sharingServiceBlockingStub.getListOfDirectlySharedGroups(request);
+    }
+
+
+    public Status shareEntityWithUsers(org.apache.custos.sharing.service.SharingRequest request) {
+        return sharingServiceBlockingStub.shareEntityWithUsers(request);
+
+    }
+
+
+    public Status shareEntityWithGroups(org.apache.custos.sharing.service.SharingRequest request) {
+        return sharingServiceBlockingStub.shareEntityWithGroups(request);
+    }
+
+
+    public Status revokeEntitySharingFromUsers(org.apache.custos.sharing.service.SharingRequest request) {
+        return sharingServiceBlockingStub.revokeEntitySharingFromUsers(request);
+    }
+
+
+    public Status revokeEntitySharingFromGroups(org.apache.custos.sharing.service.SharingRequest request) {
+        return sharingServiceBlockingStub.revokeEntitySharingFromGroups(request);
+    }
+
+
+    public Status userHasAccess(org.apache.custos.sharing.service.SharingRequest request) {
+        return sharingServiceBlockingStub.userHasAccess(request);
+    }
+
+
+}
diff --git a/custos-core-services-client-stubs/tenant-profile-core-service-client-stub/pom.xml b/custos-core-services-client-stubs/tenant-profile-core-service-client-stub/pom.xml
new file mode 100644
index 0000000..3d0b6de
--- /dev/null
+++ b/custos-core-services-client-stubs/tenant-profile-core-service-client-stub/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>tenant-profile-core-service-client-stub</artifactId>
+
+<dependencies>
+    <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+
+    <dependency>
+        <groupId>io.grpc</groupId>
+        <artifactId>grpc-stub</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>io.grpc</groupId>
+        <artifactId>grpc-protobuf</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>io.grpc</groupId>
+        <artifactId>grpc-netty</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>javax.annotation</groupId>
+        <artifactId>javax.annotation-api</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.custos</groupId>
+        <artifactId>custos-integration-core</artifactId>
+        <version>${project.version}</version>
+    </dependency>
+</dependencies>
+
+  <build>
+      <extensions>
+          <extension>
+              <groupId>kr.motd.maven</groupId>
+              <artifactId>os-maven-plugin</artifactId>
+          </extension>
+      </extensions>
+      <plugins>
+      <plugin>
+          <groupId>org.xolstice.maven.plugins</groupId>
+          <artifactId>protobuf-maven-plugin</artifactId>
+          <configuration>
+              <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+              <pluginId>grpc-java</pluginId>
+              <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+              <protoSourceRoot>../../custos-core-services/tenant-profile-core-service/src/main/proto</protoSourceRoot>
+          </configuration>
+          <executions>
+              <execution>
+                  <goals>
+                      <goal>compile</goal>
+                      <goal>compile-python</goal>
+                      <goal>compile-custom</goal>
+                  </goals>
+              </execution>
+          </executions>
+      </plugin>
+      </plugins>
+  </build>
+
+
+
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/tenant-profile-core-service-client-stub/src/main/java/org/apache/custos/tenant/profile/client/async/TenantProfileClient.java b/custos-core-services-client-stubs/tenant-profile-core-service-client-stub/src/main/java/org/apache/custos/tenant/profile/client/async/TenantProfileClient.java
new file mode 100644
index 0000000..6b059af
--- /dev/null
+++ b/custos-core-services-client-stubs/tenant-profile-core-service-client-stub/src/main/java/org/apache/custos/tenant/profile/client/async/TenantProfileClient.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.client.async;
+
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.integration.core.ServiceCallback;
+import org.apache.custos.integration.core.ServiceException;
+import org.apache.custos.tenant.profile.service.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * This class uses gRPC stubs generated for {@link TenantProfileServiceGrpc}
+ * and acts as the client
+ */
+@Component
+public class TenantProfileClient {
+
+    private ManagedChannel managedChannel;
+    private TenantProfileServiceGrpc.TenantProfileServiceStub profileServiceStub;
+    private TenantProfileServiceGrpc.TenantProfileServiceBlockingStub profileServiceBlockingStub;
+
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+
+    public TenantProfileClient(List<ClientInterceptor> clientInterceptorList,
+                               @Value("${tenant.profile.core.service.dns.name}") String serviceHost,
+                               @Value("${tenant.profile.core.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        profileServiceStub = TenantProfileServiceGrpc.newStub(managedChannel);
+        profileServiceBlockingStub = TenantProfileServiceGrpc.newBlockingStub(managedChannel);
+    }
+
+    public void addTenantAsync(Tenant tenant, final ServiceCallback callback) {
+
+        StreamObserver observer = this.getObserver(callback, "Add tenant task failed");
+
+        profileServiceStub.addTenant(tenant, observer);
+    }
+
+
+    public  Tenant addTenant(Tenant tenant) {
+        return profileServiceBlockingStub.addTenant(tenant);
+
+    }
+
+
+    public void updateTenantAsync(Tenant request, final ServiceCallback callback) {
+
+        StreamObserver observer = this.getObserver(callback, "Update tenant task failed");
+
+        profileServiceStub.updateTenant(request, observer);
+    }
+
+
+    public Tenant updateTenant(Tenant updateTenantRequest) {
+        return profileServiceBlockingStub.updateTenant(updateTenantRequest);
+    }
+
+
+    public GetAllTenantsResponse getAllTenants(GetTenantsRequest request) {
+        return profileServiceBlockingStub.getAllTenants(request);
+    }
+
+
+    public void getAllTenantsForUserAsync(GetAllTenantsForUserRequest getAllTenantsForUserRequest, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "Get all tenants for user task failed");
+
+        profileServiceStub.getAllTenantsForUser(getAllTenantsForUserRequest, observer);
+    }
+
+    public GetAllTenantsForUserResponse getAllTenantsForUser(GetAllTenantsForUserRequest getAllTenantsForUserRequest) {
+
+        return profileServiceBlockingStub.getAllTenantsForUser(getAllTenantsForUserRequest);
+    }
+
+
+    public void getTenantAsync(GetTenantRequest getTenantRequest, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "Get tenant task failed");
+
+        profileServiceStub.getTenant(getTenantRequest, observer);
+    }
+
+    public GetTenantResponse getTenant(GetTenantRequest getTenantRequest) {
+        return profileServiceBlockingStub.getTenant(getTenantRequest);
+    }
+
+    public void updateTenantStatusAsync(UpdateStatusRequest updateTenantRequest, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "Update tenant status task failed");
+
+        profileServiceStub.updateTenantStatus(updateTenantRequest, observer);
+    }
+
+    public UpdateStatusResponse updateTenantStatus(UpdateStatusRequest request) {
+        return profileServiceBlockingStub.updateTenantStatus(request);
+    }
+
+    public void getAttributeUpdateAuditTrailAsync(
+            GetAuditTrailRequest request, final ServiceCallback callback) {
+
+        StreamObserver observer = this.getObserver(callback, "Get attribute update audit trail failed");
+
+        profileServiceStub.getTenantAttributeUpdateAuditTrail(request, observer);
+    }
+
+    public GetAttributeUpdateAuditTrailResponse getAttributeUpdateAuditTrail(
+            GetAuditTrailRequest request) {
+
+        return profileServiceBlockingStub.getTenantAttributeUpdateAuditTrail(request);
+    }
+
+    public void getStatusUpdateAuditTrailAsync(GetAuditTrailRequest request,
+                                               final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "Get  status update audit trail task failed");
+
+        profileServiceStub.getTenantStatusUpdateAuditTrail(request, observer);
+    }
+
+    public GetStatusUpdateAuditTrailResponse getStatusUpdateAuditTrail(
+            GetAuditTrailRequest request) {
+
+        return profileServiceBlockingStub.getTenantStatusUpdateAuditTrail(request);
+    }
+
+    public void isTenantExistAsync(IsTenantExistRequest request, final ServiceCallback callback) {
+        StreamObserver observer = this.getObserver(callback, "Is tenant exist task failed");
+
+        profileServiceStub.isTenantExist(request, observer);
+    }
+
+
+    public IsTenantExistResponse isTenantExist(IsTenantExistRequest request) {
+        return profileServiceBlockingStub.isTenantExist(request);
+    }
+
+
+    private StreamObserver getObserver(ServiceCallback callback, String failureMsg) {
+        final Object[] response = new Object[1];
+        StreamObserver observer = new StreamObserver() {
+            @Override
+            public void onNext(Object o) {
+                response[0] = o;
+            }
+
+            @Override
+            public void onError(Throwable throwable) {
+                callback.onError(new ServiceException(failureMsg, throwable, null));
+            }
+
+            @Override
+            public void onCompleted() {
+                callback.onCompleted(response[0]);
+            }
+        };
+
+        return observer;
+    }
+
+
+}
diff --git a/custos-core-services-client-stubs/user-profile-core-service-client-stub/pom.xml b/custos-core-services-client-stubs/user-profile-core-service-client-stub/pom.xml
new file mode 100644
index 0000000..718de29
--- /dev/null
+++ b/custos-core-services-client-stubs/user-profile-core-service-client-stub/pom.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services-client-stubs</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>user-profile-core-service-client-stub</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                    <protoSourceRoot>../../custos-core-services/user-profile-core-service/src/main/proto</protoSourceRoot>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-python</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services-client-stubs/user-profile-core-service-client-stub/src/main/java/org/apache/custos/user/profile/client/UserProfileClient.java b/custos-core-services-client-stubs/user-profile-core-service-client-stub/src/main/java/org/apache/custos/user/profile/client/UserProfileClient.java
new file mode 100644
index 0000000..3fa8f88
--- /dev/null
+++ b/custos-core-services-client-stubs/user-profile-core-service-client-stub/src/main/java/org/apache/custos/user/profile/client/UserProfileClient.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.client;
+
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.integration.core.ServiceCallback;
+import org.apache.custos.integration.core.ServiceException;
+import org.apache.custos.user.profile.service.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * This class is used to connect with user profile service
+ */
+@Component
+public class UserProfileClient {
+
+    private ManagedChannel managedChannel;
+    private UserProfileServiceGrpc.UserProfileServiceStub userProfileServiceStub;
+    private UserProfileServiceGrpc.UserProfileServiceBlockingStub userProfileServiceBlockingStub;
+
+
+    private final List<ClientInterceptor> clientInterceptorList;
+
+
+    public UserProfileClient(List<ClientInterceptor> clientInterceptorList,
+                             @Value("${user.profile.core.service.dns.name}") String serviceHost,
+                             @Value("${user.profile.core.service.port}") int servicePort) {
+        this.clientInterceptorList = clientInterceptorList;
+        managedChannel = ManagedChannelBuilder.forAddress(
+                serviceHost, servicePort).usePlaintext(true).intercept(clientInterceptorList).build();
+        userProfileServiceStub = UserProfileServiceGrpc.newStub(managedChannel);
+        userProfileServiceBlockingStub = UserProfileServiceGrpc.newBlockingStub(managedChannel);
+    }
+
+
+    public void createUserProfileAsync(UserProfileRequest profile, final ServiceCallback callback) {
+
+        StreamObserver observer = this.getObserver(callback, "Create user profile task failed");
+
+        userProfileServiceStub.createUserProfile(profile, observer);
+    }
+
+
+    public void updateUserProfileAsync(UserProfileRequest profile, final ServiceCallback callback) {
+
+        StreamObserver observer = this.getObserver(callback, "Update user profile task failed");
+
+        userProfileServiceStub.updateUserProfile(profile, observer);
+    }
+
+
+    public void getUserAsync(UserProfileRequest request, final ServiceCallback callback) {
+
+        StreamObserver observer = this.getObserver(callback, "get user profile task failed");
+
+        userProfileServiceStub.getUserProfile(request, observer);
+    }
+
+
+    public void deleteUserAsync(UserProfileRequest request, final ServiceCallback callback) {
+
+        StreamObserver observer = this.getObserver(callback, "delete user profile task failed");
+
+        userProfileServiceStub.deleteUserProfile(request, observer);
+    }
+
+
+    public void getUserProfileUpdateAuditTrailAsync(org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest request,
+                                                    final ServiceCallback callback) {
+
+        StreamObserver observer = this.getObserver(callback, "get user profile update audit trail failed");
+
+        userProfileServiceStub.getUserProfileAuditTrails(request, observer);
+    }
+
+
+    public void getAllUserProfilesInTenantAsync(UserProfileRequest request,
+                                                final ServiceCallback callback) {
+
+        StreamObserver observer = this.getObserver(callback, "get all user profiles in tenant async");
+
+        userProfileServiceStub.getAllUserProfilesInTenant(request, observer);
+    }
+
+    public UserProfile createUserProfile(UserProfileRequest profile) {
+        return userProfileServiceBlockingStub.createUserProfile(profile);
+    }
+
+
+    public UserProfile updateUserProfile(UserProfileRequest profile) {
+
+        return userProfileServiceBlockingStub.updateUserProfile(profile);
+    }
+
+
+    public UserProfile getUser(UserProfileRequest request) {
+
+        return userProfileServiceBlockingStub.getUserProfile(request);
+    }
+
+
+    public UserProfile deleteUser(UserProfileRequest request) {
+
+        return userProfileServiceBlockingStub.deleteUserProfile(request);
+    }
+
+
+    public org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse getUserProfileUpdateAuditTrail(
+            org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest request) {
+
+        return userProfileServiceBlockingStub.getUserProfileAuditTrails(request);
+    }
+
+
+    public GetAllUserProfilesResponse getAllUserProfilesInTenant(UserProfileRequest request) {
+        return userProfileServiceBlockingStub.getAllUserProfilesInTenant(request);
+    }
+
+    public GetAllUserProfilesResponse findUserProfilesByUserAttributes(UserProfileRequest request) {
+        return userProfileServiceBlockingStub.findUserProfilesByAttributes(request);
+    }
+
+    public Group createGroup(GroupRequest request) {
+        return userProfileServiceBlockingStub.createGroup(request);
+    }
+
+    public Group updateGroup(GroupRequest request) {
+        return userProfileServiceBlockingStub.updateGroup(request);
+    }
+
+    public Group deleteGroup(GroupRequest request) {
+        return userProfileServiceBlockingStub.deleteGroup(request);
+    }
+
+    public Group getGroup(GroupRequest request) {
+        return userProfileServiceBlockingStub.getGroup(request);
+    }
+
+
+    public GetAllGroupsResponse getAllGroups(GroupRequest request) {
+        return userProfileServiceBlockingStub.getAllGroups(request);
+    }
+
+    public Status addUserToGroup(GroupMembership request) {
+        return userProfileServiceBlockingStub.addUserToGroup(request);
+    }
+
+    public Status removeUserFromGroup(GroupMembership request) {
+        return userProfileServiceBlockingStub.removeUserFromGroup(request);
+    }
+
+    public Status addChildGroupToParentGroup(GroupToGroupMembership request) {
+        return userProfileServiceBlockingStub.addChildGroupToParentGroup(request);
+    }
+
+    public Status removeChildGroupFromParentGroup(GroupToGroupMembership request) {
+        return userProfileServiceBlockingStub.removeChildGroupFromParentGroup(request);
+    }
+
+    public GetAllGroupsResponse getAllGroupsOfUser(UserProfileRequest request) {
+        return userProfileServiceBlockingStub.getAllGroupsOfUser(request);
+    }
+
+    public GetAllGroupsResponse getAllParentGroupsOfGroup(GroupRequest request) {
+
+        return userProfileServiceBlockingStub.getAllParentGroupsOfGroup(request);
+    }
+
+
+    public GetAllUserProfilesResponse getAllChildUsers(GroupRequest request) {
+        return userProfileServiceBlockingStub.getAllChildUsers(request);
+    }
+
+    public GetAllGroupsResponse getAllChildGroups(GroupRequest request) {
+        return userProfileServiceBlockingStub.getAllChildGroups(request);
+    }
+
+    public Status changeUserMembershipType(GroupMembership request) {
+        return userProfileServiceBlockingStub.changeUserMembershipType(request);
+    }
+
+    public Status hasAccess(GroupMembership request) {
+        return userProfileServiceBlockingStub.hasAccess(request);
+    }
+
+
+    private StreamObserver getObserver(ServiceCallback callback, String failureMsg) {
+        final Object[] response = new Object[1];
+        StreamObserver observer = new StreamObserver() {
+            @Override
+            public void onNext(Object o) {
+                response[0] = o;
+            }
+
+            @Override
+            public void onError(Throwable throwable) {
+                callback.onError(new ServiceException(failureMsg, throwable, null));
+            }
+
+            @Override
+            public void onCompleted() {
+                callback.onCompleted(response[0]);
+            }
+        };
+
+        return observer;
+    }
+
+}
diff --git a/custos-core-services/agent-profile-core-service/Dockerfile b/custos-core-services/agent-profile-core-service/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/agent-profile-core-service/pom.xml b/custos-core-services/agent-profile-core-service/pom.xml
new file mode 100644
index 0000000..6c4ca1f
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/pom.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>agent-profile-core-service</artifactId>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/.helmignore b/custos-core-services/agent-profile-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/Chart.yaml b/custos-core-services/agent-profile-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..2c33a48
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of custos agent profile service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/agent-profile-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/agent-profile-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/agent-profile-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..ab67be6
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,66 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  strategy:
+    type: RollingUpdate
+    rollingUpdate:
+      maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+      maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/agent-profile-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/templates/service.yaml b/custos-core-services/agent-profile-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/agent-profile-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/agent-profile-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/agent-profile-core-service/src/main/helm/values.yaml b/custos-core-services/agent-profile-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..93eb74d
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/helm/values.yaml
@@ -0,0 +1,78 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/AgentProfileServiceInitializer.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/AgentProfileServiceInitializer.java
new file mode 100644
index 0000000..47b74cb
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/AgentProfileServiceInitializer.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.agent.profile.validator.InputValidator;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+
+@SpringBootApplication
+@EnableJpaAuditing
+public class AgentProfileServiceInitializer {
+
+    public static void main(String[] args) {
+        SpringApplication.run(AgentProfileServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator){
+        return new ServiceInterceptor(validator);
+    }
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/mapper/AgentMapper.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/mapper/AgentMapper.java
new file mode 100644
index 0000000..0cbbf0b
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/mapper/AgentMapper.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.mapper;
+
+import org.apache.custos.agent.profile.persistance.model.Agent;
+import org.apache.custos.agent.profile.persistance.model.AgentAttribute;
+import org.apache.custos.agent.profile.persistance.model.AgentRole;
+import org.apache.custos.agent.profile.service.AgentStatus;
+import org.apache.custos.agent.profile.utils.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+/**
+ * Mapping class of service models to persistence model
+ */
+public class AgentMapper {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AgentMapper.class);
+
+
+    public static Agent createAgent(org.apache.custos.agent.profile.service.Agent agent, long tenantId) {
+
+        Agent persistenceModel = new Agent();
+
+        persistenceModel.setTenantId(tenantId);
+        persistenceModel.setStatus(agent.getStatus().name());
+        persistenceModel.setAgentId(agent.getId());
+
+
+
+        Set<AgentAttribute> attributeSet = new HashSet<>();
+        if (agent.getAttributesList() != null && !agent.getAttributesList().isEmpty()) {
+
+            agent.getAttributesList().forEach(atr -> {
+                if (atr.getValueList() != null && !atr.getValueList().isEmpty()) {
+                    for (String value : atr.getValueList()) {
+                        AgentAttribute userAttribute = new AgentAttribute();
+                        userAttribute.setKeyValue(atr.getKey());
+                        userAttribute.setValue(value);
+                        userAttribute.setAgent(persistenceModel);
+                        attributeSet.add(userAttribute);
+                    }
+                }
+            });
+        }
+        persistenceModel.setAgentAttribute(attributeSet);
+        Set<AgentRole> userRoleSet = new HashSet<>();
+        if (agent.getRolesList() != null && !agent.getRolesList().isEmpty()) {
+
+            agent.getRolesList().forEach(role -> {
+                AgentRole userRole = new AgentRole();
+                userRole.setValue(role);
+                userRole.setType(Constants.ROLE_TYPE_REALM);
+                userRole.setAgent(persistenceModel);
+                userRoleSet.add(userRole);
+            });
+        }
+
+
+        if (agent.getAgentClientRolesList() != null && !agent.getAgentClientRolesList().isEmpty()) {
+
+            agent.getAgentClientRolesList().forEach(role -> {
+                AgentRole userRole = new AgentRole();
+                userRole.setValue(role);
+                userRole.setType(Constants.ROLE_TYPE_CLIENT);
+                userRole.setAgent(persistenceModel);
+                userRoleSet.add(userRole);
+            });
+        }
+
+
+        persistenceModel.setAgentRole(userRoleSet);
+
+        return persistenceModel;
+    }
+
+
+    public static org.apache.custos.agent.profile.service.Agent createAgent(Agent agent) {
+
+        org.apache.custos.agent.profile.service.Agent serviceAgent =
+                org.apache.custos.agent.profile.service.Agent
+                        .newBuilder()
+                        .setId(agent.getAgentId() == null? agent.getId():agent.getAgentId())
+                        .setCreatedAt(agent.getCreatedAt().getTime())
+                        .setLastModifiedAt(agent.getLast_modified_at().getTime())
+                        .setStatus(AgentStatus.valueOf(agent.getStatus()))
+                        .build();
+
+        List<org.apache.custos.agent.profile.service.AgentAttribute> attributeList = new ArrayList<>();
+        if (agent.getAgentAttribute() != null && !agent.getAgentAttribute().isEmpty()) {
+
+            Map<String, List<String>> atrMap = new HashMap<>();
+
+            agent.getAgentAttribute().forEach(atr -> {
+
+                if (atrMap.get(atr.getKeyValue()) == null) {
+                    atrMap.put(atr.getKeyValue(), new ArrayList<String>());
+                }
+                atrMap.get(atr.getKeyValue()).add(atr.getValue());
+
+            });
+
+
+            atrMap.keySet().forEach(key -> {
+                org.apache.custos.agent.profile.service.AgentAttribute attribute = org.apache.custos.agent.profile.service
+                        .AgentAttribute
+                        .newBuilder()
+                        .setKey(key)
+                        .addAllValue(atrMap.get(key))
+                        .build();
+                attributeList.add(attribute);
+            });
+        }
+
+        List<String> roleList = new ArrayList<>();
+        List<String> clientList = new ArrayList<>();
+
+        if (agent.getAgentRole() != null && !agent.getAgentRole().isEmpty()) {
+
+            agent.getAgentRole().forEach(role -> {
+                if (role.getType().equals(Constants.ROLE_TYPE_REALM)) {
+                    roleList.add(role.getValue());
+                } else if (role.getType().equals(Constants.ROLE_TYPE_CLIENT)) {
+                    clientList.add(role.getValue());
+                }
+            });
+        }
+
+        serviceAgent = serviceAgent.toBuilder()
+                .addAllRoles(roleList)
+                .addAllAgentClientRoles(clientList)
+                .addAllAttributes(attributeList)
+                .build();
+
+
+        return serviceAgent;
+
+    }
+
+
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/model/Agent.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/model/Agent.java
new file mode 100644
index 0000000..3d27eca
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/model/Agent.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * Agent entity
+ */
+@Entity
+@Table(name = "agent_entity")
+@EntityListeners(AuditingEntityListener.class)
+public class Agent {
+
+    @Id
+    private String id;
+
+    @Column(nullable = false)
+    private Long tenantId;
+
+    @Column(nullable = false)
+    private String status;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date last_modified_at;
+
+
+    private String agentId;
+
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "agent", orphanRemoval = true, cascade = CascadeType.ALL)
+    private Set<AgentRole> agentRole;
+
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "agent", orphanRemoval = true, cascade = CascadeType.ALL)
+    private Set<AgentAttribute> agentAttribute;
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLast_modified_at() {
+        return last_modified_at;
+    }
+
+    public void setLast_modified_at(Date last_modified_at) {
+        this.last_modified_at = last_modified_at;
+    }
+
+    public Set<AgentRole> getAgentRole() {
+        return agentRole;
+    }
+
+    public void setAgentRole(Set<AgentRole> agentRole) {
+        this.agentRole = agentRole;
+    }
+
+    public Set<AgentAttribute> getAgentAttribute() {
+        return agentAttribute;
+    }
+
+    public void setAgentAttribute(Set<AgentAttribute> agentAttribute) {
+        this.agentAttribute = agentAttribute;
+    }
+
+    public String getAgentId() {
+        return agentId;
+    }
+
+    public void setAgentId(String agentId) {
+        this.agentId = agentId;
+    }
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/model/AgentAttribute.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/model/AgentAttribute.java
new file mode 100644
index 0000000..c209a5a
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/model/AgentAttribute.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.persistance.model;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "agent_attribute")
+public class AgentAttribute {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String keyValue;
+
+    @Column(nullable = false)
+    private String value;
+
+    @ManyToOne
+    @JoinColumn(name = "agent_entity_id")
+    private Agent agent;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getKeyValue() {
+        return keyValue;
+    }
+
+    public void setKeyValue(String keyValue) {
+        this.keyValue = keyValue;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public Agent getAgent() {
+        return agent;
+    }
+
+    public void setAgent(Agent agent) {
+        this.agent = agent;
+    }
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/model/AgentRole.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/model/AgentRole.java
new file mode 100644
index 0000000..9b0943a
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/model/AgentRole.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.persistance.model;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "agent_role")
+public class AgentRole {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String type;
+
+    @Column(nullable = false)
+    private String value;
+
+    @ManyToOne
+    @JoinColumn(name = "agent_entity_id")
+    private Agent agent;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public Agent getAgent() {
+        return agent;
+    }
+
+    public void setAgent(Agent agent) {
+        this.agent = agent;
+    }
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/repository/AgentAttributeRepository.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/repository/AgentAttributeRepository.java
new file mode 100644
index 0000000..a0c15d4
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/repository/AgentAttributeRepository.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.persistance.repository;
+
+import org.apache.custos.agent.profile.persistance.model.AgentAttribute;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AgentAttributeRepository extends JpaRepository<AgentAttribute, String> {
+
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/repository/AgentRepository.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/repository/AgentRepository.java
new file mode 100644
index 0000000..f1df24d
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/repository/AgentRepository.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.persistance.repository;
+
+import org.apache.custos.agent.profile.persistance.model.Agent;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AgentRepository extends JpaRepository<Agent, String> {
+
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/repository/AgentRoleRepository.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/repository/AgentRoleRepository.java
new file mode 100644
index 0000000..388bbba
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/persistance/repository/AgentRoleRepository.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.persistance.repository;
+
+import org.apache.custos.agent.profile.persistance.model.AgentRole;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AgentRoleRepository extends JpaRepository<AgentRole, String> {
+
+}
+
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/service/AgentProfileService.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/service/AgentProfileService.java
new file mode 100644
index 0000000..be600cc
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/service/AgentProfileService.java
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.service;
+
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.agent.profile.mapper.AgentMapper;
+import org.apache.custos.agent.profile.persistance.repository.AgentAttributeRepository;
+import org.apache.custos.agent.profile.persistance.repository.AgentRepository;
+import org.apache.custos.agent.profile.persistance.repository.AgentRoleRepository;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Optional;
+
+@GRpcService
+public class AgentProfileService extends AgentProfileServiceGrpc.AgentProfileServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AgentProfileService.class);
+
+
+    @Autowired
+    private AgentRepository agentRepository;
+
+    @Autowired
+    private AgentRoleRepository agentRoleRepository;
+
+    @Autowired
+    private AgentAttributeRepository agentAttributeRepository;
+
+
+    @Override
+    public void createAgent(AgentRequest request, StreamObserver<Agent> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createAgent for " + request.getAgent().getId() + "at " + request.getTenantId());
+
+            String agentId = request.getAgent().getId() + "@" + request.getTenantId();
+
+            Optional<org.apache.custos.agent.profile.persistance.model.Agent> op = agentRepository.findById(agentId);
+
+            if (op.isEmpty()) {
+
+                org.apache.custos.agent.profile.persistance.model.Agent entity =
+                        AgentMapper.createAgent(request.getAgent(), request.getTenantId());
+                entity.setId(agentId);
+                agentRepository.save(entity);
+
+                Optional<org.apache.custos.agent.profile.persistance.model.Agent> optionalAgent =
+                        agentRepository.findById(agentId);
+
+                if (optionalAgent.isPresent()) {
+
+                    Agent ex = AgentMapper.createAgent(optionalAgent.get());
+
+                    responseObserver.onNext(ex);
+                    responseObserver.onCompleted();
+
+                } else {
+                    String msg = "Error occurred while creating agent, agent is not saved";
+                    LOGGER.error(msg);
+                    responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+
+                }
+
+            } else {
+                String msg = "Error occurred while creating agent already exists";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.ALREADY_EXISTS.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while creating agent for " + request.getAgent().getId() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void updateAgent(AgentRequest request, StreamObserver<Agent> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateAgent for " + request.getAgent().getId() + "at " + request.getTenantId());
+
+            String userId = request.getAgent().getId() + "@" + request.getTenantId();
+
+            Optional<org.apache.custos.agent.profile.persistance.model.Agent>
+                    exEntity = agentRepository.findById(userId);
+
+            Optional<org.apache.custos.agent.profile.persistance.model.Agent>
+                    preEntity = agentRepository.findById(request.getAgent().getId());
+            if (exEntity.isEmpty()) {
+                exEntity = preEntity;
+                userId = request.getAgent().getId();
+            }
+
+            if (exEntity.isPresent()) {
+
+                org.apache.custos.agent.profile.persistance.model.Agent entity =
+                        AgentMapper.createAgent(request.getAgent(), request.getTenantId());
+                entity.setId(exEntity.get().getId());
+                entity.setCreatedAt(exEntity.get().getCreatedAt());
+
+                org.apache.custos.agent.profile.persistance.model.Agent exProfile = exEntity.get();
+
+                if (exProfile.getAgentAttribute() != null) {
+                    exProfile.getAgentAttribute().forEach(atr -> {
+                        agentAttributeRepository.delete(atr);
+
+                    });
+                }
+
+                if (exProfile.getAgentRole() != null) {
+                    exProfile.getAgentRole().forEach(role -> {
+                        agentRoleRepository.delete(role);
+                    });
+                }
+
+                agentRepository.save(entity);
+
+                Optional<org.apache.custos.agent.profile.persistance.model.Agent> optionalAgent =
+                        agentRepository.findById(userId);
+
+                if (optionalAgent.isPresent()) {
+
+                    Agent ex = AgentMapper.createAgent(optionalAgent.get());
+
+                    responseObserver.onNext(ex);
+                    responseObserver.onCompleted();
+
+                } else {
+                    String msg = "Error occurred while updating agent, agent is not saved";
+                    LOGGER.error(msg);
+                    responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+
+                }
+            } else {
+                String msg = "Cannot find a agent for " + userId;
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while updating agent for " + request.getAgent().getId() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteAgent(AgentRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteAgent for " + request.getAgent().getId() + "at " + request.getTenantId());
+
+            String id = request.getAgent().getId() + "@" + request.getTenantId();
+
+            Optional<org.apache.custos.agent.profile.persistance.model.Agent> agentOptional = agentRepository.findById(id);
+            Optional<org.apache.custos.agent.profile.persistance.model.Agent>
+                    preEntity = agentRepository.findById(request.getAgent().getId());
+            if (agentOptional.isEmpty()) {
+                agentOptional = preEntity;
+            }
+
+
+            if (agentOptional.isPresent()) {
+
+                agentRepository.delete(agentOptional.get());
+                OperationStatus status = OperationStatus.newBuilder().setStatus(true).build();
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+            } else {
+                responseObserver.onError(Status.NOT_FOUND.withDescription("Agent not found")
+                        .asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting agent for " + request.getAgent().getId() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAgent(AgentRequest request, StreamObserver<Agent> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAgent for " + request.getAgent().getId() + "at " + request.getTenantId());
+
+            String id = request.getAgent().getId() + "@" + request.getTenantId();
+
+            Optional<org.apache.custos.agent.profile.persistance.model.Agent> agentOptional = agentRepository.findById(id);
+
+            Optional<org.apache.custos.agent.profile.persistance.model.Agent>
+                    preEntity = agentRepository.findById(request.getAgent().getId());
+            if (agentOptional.isEmpty()) {
+                agentOptional = preEntity;
+            }
+
+            if (agentOptional.isPresent()) {
+
+
+                Agent agent = AgentMapper.createAgent(agentOptional.get());
+
+                responseObserver.onNext(agent);
+                responseObserver.onCompleted();
+            } else {
+
+                responseObserver.onNext(null);
+                responseObserver.onCompleted();
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching agent for " + request.getAgent().getId() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/utils/Constants.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/utils/Constants.java
new file mode 100644
index 0000000..0304d7c
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/utils/Constants.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.utils;
+
+public final class Constants {
+    public static final String ROLE_TYPE_REALM = "realm";
+    public static final  String ROLE_TYPE_CLIENT = "client";
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/validator/InputValidator.java b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/validator/InputValidator.java
new file mode 100644
index 0000000..ed516e1
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/validator/InputValidator.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.profile.validator;
+
+import org.apache.custos.agent.profile.service.AgentRequest;
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.core.services.commons.exceptions.MissingParameterException;
+
+/**
+ * This class validates the  requests
+ */
+public class InputValidator implements Validator {
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "createAgent":
+            case "updateAgent":
+            case "deleteAgent":
+            case "getAgent":
+                validateAgentRequest(obj);
+                break;
+            default:
+
+        }
+
+    }
+
+    private boolean validateAgentRequest(Object obj) {
+        if (obj instanceof AgentRequest) {
+            AgentRequest request = (AgentRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("TenantId should not be null", null);
+            }
+            if (request.getAgent() == null) {
+                throw new MissingParameterException("Agent should not be null", null);
+            }
+
+            if (request.getAgent().getId() == null || request.getAgent().getId().equals("")) {
+                throw new MissingParameterException("AgentId should not be null", null);
+            }
+
+        }
+        return true;
+    }
+
+
+}
diff --git a/custos-core-services/agent-profile-core-service/src/main/proto/AgentProfileService.proto b/custos-core-services/agent-profile-core-service/src/main/proto/AgentProfileService.proto
new file mode 100644
index 0000000..6ded328
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/proto/AgentProfileService.proto
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.agent.profile.service;
+
+message Agent {
+    string id = 1;
+    AgentStatus status = 2;
+    int64 created_at = 3;
+    int64 last_modified_at = 4;
+    repeated string roles = 5;
+    repeated AgentAttribute attributes = 6;
+    repeated string agent_client_roles = 8;
+
+}
+
+enum AgentStatus {
+    ENABLED = 0;
+    DISABLED = 1;
+}
+
+message AgentAttribute {
+    string id = 1;
+    string key = 2;
+    repeated string value = 3;
+}
+
+message AgentRequest {
+    int64 tenantId = 1;
+    Agent agent = 2;
+}
+
+message OperationStatus {
+    bool status = 1;
+}
+
+service AgentProfileService {
+
+    rpc createAgent (AgentRequest) returns (Agent);
+    rpc updateAgent (AgentRequest) returns (Agent);
+    rpc deleteAgent (AgentRequest) returns (OperationStatus);
+    rpc getAgent (AgentRequest) returns (Agent);
+
+}
\ No newline at end of file
diff --git a/custos-core-services/agent-profile-core-service/src/main/resources/application.properties b/custos-core-services/agent-profile-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..5fb3e72
--- /dev/null
+++ b/custos-core-services/agent-profile-core-service/src/main/resources/application.properties
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=agentProfileCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_agent_profile?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
\ No newline at end of file
diff --git a/custos-core-services/cluster-management-core-service/Dockerfile b/custos-core-services/cluster-management-core-service/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/cluster-management-core-service/pom.xml b/custos-core-services/cluster-management-core-service/pom.xml
new file mode 100644
index 0000000..eb51471
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/pom.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>cluster-management-core-service</artifactId>
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.kubernetes</groupId>
+            <artifactId>client-java</artifactId>
+        </dependency>
+
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/.helmignore b/custos-core-services/cluster-management-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/Chart.yaml b/custos-core-services/cluster-management-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..644a099
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of kube cluster controller
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/cluster-management-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/cluster-management-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/cluster-management-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..ab67be6
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,66 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  strategy:
+    type: RollingUpdate
+    rollingUpdate:
+      maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+      maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/cluster-management-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/templates/role-bindings.yaml b/custos-core-services/cluster-management-core-service/src/main/helm/templates/role-bindings.yaml
new file mode 100644
index 0000000..6989d73
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/templates/role-bindings.yaml
@@ -0,0 +1,11 @@
+kind: RoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: {{ .Values.role.binding }}
+subjects:
+  - kind: ServiceAccount
+    name: {{ template "helm.serviceAccountName" . }}
+roleRef:
+  kind: Role
+  name: {{ .Values.role.name }}
+  apiGroup: rbac.authorization.k8s.io
\ No newline at end of file
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/templates/role.yaml b/custos-core-services/cluster-management-core-service/src/main/helm/templates/role.yaml
new file mode 100644
index 0000000..4c4a9ae
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/templates/role.yaml
@@ -0,0 +1,22 @@
+kind: Role
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: {{ .Values.role.name }}
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - namespaces
+    verbs:
+      - get
+  - apiGroups:
+      - ""
+    resources:
+      - configmaps
+      - pods
+      - secrets
+      - endpoints
+    verbs:
+      - get
+      - list
+      - watch
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/templates/service.yaml b/custos-core-services/cluster-management-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/cluster-management-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/cluster-management-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/cluster-management-core-service/src/main/helm/values.yaml b/custos-core-services/cluster-management-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..a615342
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/helm/values.yaml
@@ -0,0 +1,82 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+role:
+  name: resource-fetch
+  binding: resource-role-binder
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/ClusterManagementServiceInitializer.java b/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/ClusterManagementServiceInitializer.java
new file mode 100644
index 0000000..57e72fb
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/ClusterManagementServiceInitializer.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.cluster.management;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.cluster.management.validator.InputValidator;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableJpaRepositories(basePackages = "org.apache.custos")
+@ComponentScan(basePackages = "org.apache.custos")
+@EntityScan(basePackages = "org.apache.custos")
+public class ClusterManagementServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(ClusterManagementServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator){
+        return new ServiceInterceptor(validator);
+    }
+}
diff --git a/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/service/ClusterManagementService.java b/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/service/ClusterManagementService.java
new file mode 100644
index 0000000..29ac714
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/service/ClusterManagementService.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.cluster.management.service;
+
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import io.kubernetes.client.ApiClient;
+import io.kubernetes.client.Configuration;
+import io.kubernetes.client.apis.CoreV1Api;
+import io.kubernetes.client.models.V1Secret;
+import io.kubernetes.client.util.ClientBuilder;
+import org.apache.custos.cluster.management.service.ClusterManagementServiceGrpc.ClusterManagementServiceImplBase;
+import org.apache.custos.core.services.commons.StatusUpdater;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+import java.util.Map;
+
+@GRpcService
+public class ClusterManagementService extends ClusterManagementServiceImplBase {
+
+    private static Logger LOGGER = LoggerFactory.getLogger(ClusterManagementService.class);
+
+    @Autowired
+    private StatusUpdater statusUpdater;
+
+    @Value("${custos.server.secret.name:tls-secret}")
+    private String custosServerSecretName;
+
+    @Value("${custos.server.kube.namespace:custos}")
+    private String custosNameSpace;
+
+    @Override
+    public void getCustosServerCertificate(org.apache.custos.cluster.management.service.GetServerCertificateRequest request,
+                                           StreamObserver<org.apache.custos.cluster.management.service.GetServerCertificateResponse> responseObserver) {
+        try {
+
+            ApiClient client = ClientBuilder.cluster().build();
+
+            // set the global default api-client to the in-cluster one from above
+            Configuration.setDefaultApiClient(client);
+
+            // the CoreV1Api loads default api-client from global configuration.
+            CoreV1Api api = new CoreV1Api();
+
+            V1Secret secret = api.readNamespacedSecret(custosServerSecretName, custosNameSpace, null, null, null);
+            Map<String, byte[]> map = secret.getData();
+            byte[] cert = map.get("tls.crt");
+            if (cert == null || cert.length == 0) {
+                GetServerCertificateResponse response = GetServerCertificateResponse.newBuilder().build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            } else {
+                String certificate = new String(cert);
+                GetServerCertificateResponse response = GetServerCertificateResponse
+                        .newBuilder()
+                        .setCertificate(certificate)
+                        .build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching custos server certificate" + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+}
diff --git a/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/util/ClusterManagementOperations.java b/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/util/ClusterManagementOperations.java
new file mode 100644
index 0000000..8e10011
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/util/ClusterManagementOperations.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.cluster.management.util;
+
+public enum  ClusterManagementOperations {
+}
diff --git a/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/validator/InputValidator.java b/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/validator/InputValidator.java
new file mode 100644
index 0000000..8a19a28
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/java/org/apache/custos/cluster/management/validator/InputValidator.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.cluster.management.validator;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.custos.cluster.management.service.GetServerCertificateRequest;
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.core.services.commons.exceptions.MissingParameterException;
+
+/**
+ * This class validates the  requests
+ */
+public class InputValidator implements Validator {
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "getCustosServerCertificate":
+                validateGetCustosServerCertificate(obj, methodName);
+                break;
+            default:
+                throw new NotImplementedException("UnImplemented method");
+
+        }
+
+
+    }
+
+    private boolean validateGetCustosServerCertificate(Object obj, String method) {
+
+        if (obj instanceof GetServerCertificateRequest) {
+           return true;
+        }
+        return true;
+    }
+
+}
diff --git a/custos-core-services/cluster-management-core-service/src/main/proto/ClusterManagementService.proto b/custos-core-services/cluster-management-core-service/src/main/proto/ClusterManagementService.proto
new file mode 100644
index 0000000..9739d06
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/proto/ClusterManagementService.proto
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.cluster.management.service;
+
+message GetServerCertificateRequest {
+    string secretName = 1;
+    string namespace = 2;
+}
+
+message GetServerCertificateResponse {
+    string certificate = 1;
+}
+
+
+
+
+service ClusterManagementService {
+
+    rpc getCustosServerCertificate (GetServerCertificateRequest) returns (GetServerCertificateResponse);
+
+}
\ No newline at end of file
diff --git a/custos-core-services/cluster-management-core-service/src/main/resources/application.properties b/custos-core-services/cluster-management-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..3768b33
--- /dev/null
+++ b/custos-core-services/cluster-management-core-service/src/main/resources/application.properties
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=clusterManagementCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_cluster_manager?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
\ No newline at end of file
diff --git a/custos-core-services/credential-store-core-service/Dockerfile b/custos-core-services/credential-store-core-service/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/credential-store-core-service/pom.xml b/custos-core-services/credential-store-core-service/pom.xml
new file mode 100644
index 0000000..75a354e
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/pom.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>credential-store-core-service</artifactId>
+    <dependencies>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-actuator</artifactId>
+    </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-vault-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/.helmignore b/custos-core-services/credential-store-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/Chart.yaml b/custos-core-services/credential-store-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..da72250
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of custos credential store service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/credential-store-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/credential-store-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/credential-store-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..31e54a6
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,64 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/credential-store-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/templates/service.yaml b/custos-core-services/credential-store-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/credential-store-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/credential-store-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/credential-store-core-service/src/main/helm/values.yaml b/custos-core-services/credential-store-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..93eb74d
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/helm/values.yaml
@@ -0,0 +1,78 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/CredentialStoreServiceInitializer.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/CredentialStoreServiceInitializer.java
new file mode 100644
index 0000000..59366bd
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/CredentialStoreServiceInitializer.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store;
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.apache.custos.credential.store.validator.InputValidator;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+/**
+ * Bootstrapping class of credential store service class
+ */
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableJpaRepositories(basePackages = "org.apache.custos")
+@ComponentScan(basePackages = "org.apache.custos")
+@EntityScan(basePackages = "org.apache.custos")
+public class CredentialStoreServiceInitializer {
+
+    public static void main(String[] args) {
+        SpringApplication.run(CredentialStoreServiceInitializer.class, args);
+    }
+
+
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator){
+        return new ServiceInterceptor(validator);
+    }
+
+
+}
+
+
+
+
+
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/credential/CredentialManager.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/credential/CredentialManager.java
new file mode 100644
index 0000000..c9e7b83
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/credential/CredentialManager.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.credential;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.custos.credential.store.exceptions.CredentialGenerationException;
+import org.apache.custos.credential.store.model.Credential;
+import org.apache.custos.credential.store.model.CredentialTypes;
+import org.apache.custos.credential.store.persistance.model.AgentCredentialEntity;
+import org.apache.custos.credential.store.persistance.model.CredentialEntity;
+import org.apache.custos.credential.store.persistance.repository.AgentCredentialRepository;
+import org.apache.custos.credential.store.persistance.repository.CredentialRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.security.SecureRandom;
+import java.util.Base64;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Random;
+
+/**
+ * A class used to generate clientId and clientSecret for custos
+ */
+@Component
+public class CredentialManager {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CredentialManager.class);
+
+    private String credentialPrefix = "custos-";
+
+    private static final Random RANDOM = new SecureRandom();
+
+    private static final String ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+    private static final int ID_LENGTH = 20;
+
+    private static final int SECRET_LENGTH = 40;
+
+    @Autowired
+    private CredentialRepository repository;
+
+    @Autowired
+    private AgentCredentialRepository agentCredentialRepository;
+
+
+    public Credential generateCredential(long ownerId, CredentialTypes type, long validTime) {
+        try {
+
+            String clientId = credentialPrefix + generateRandomClientId(ID_LENGTH).toLowerCase() + "-" + ownerId;
+
+            String secret = generateSecret(SECRET_LENGTH);
+
+            Credential credential = new Credential();
+            CredentialEntity entity = new CredentialEntity();
+
+            entity.setClientId(clientId);
+            entity.setClientSecretExpiredAt(0);
+            entity.setOwnerId(ownerId);
+            entity.setType(type.name());
+
+            credential.setId(clientId);
+            credential.setSecret(secret);
+
+            repository.save(entity);
+
+            return credential;
+        } catch (Exception exception) {
+            throw new CredentialGenerationException
+                    ("Error occurred while generating credentials for " + ownerId, exception);
+        }
+
+    }
+
+
+    public Credential generateAgentCredential(long ownerId, String id, CredentialTypes type, long validTime) {
+        try {
+
+            Optional<CredentialEntity> exEntity = repository.findById(ownerId);
+
+            if (exEntity.isPresent()) {
+
+                String secret = generateSecret(SECRET_LENGTH);
+                String password = generateSecret(SECRET_LENGTH);
+
+                Credential credential = new Credential();
+                AgentCredentialEntity entity = new AgentCredentialEntity();
+
+                entity.setClientId(id);
+                entity.setClientSecretExpiredAt(0);
+                entity.setOwnerId(ownerId);
+                entity.setType(type.name());
+
+                credential.setId(id);
+                credential.setSecret(secret);
+                credential.setPassword(password);
+
+                agentCredentialRepository.save(entity);
+
+                return credential;
+
+            } else {
+                throw new CredentialGenerationException
+                        ("Cannot find a registered client for  " + ownerId, null);
+            }
+
+
+        } catch (Exception ex) {
+            throw new CredentialGenerationException
+                    ("Error occurred while generating agent credentials for " + ownerId, ex);
+        }
+
+    }
+
+
+    public Credential decodeToken(String token) {
+
+        try {
+            byte[] array = Base64.getDecoder().decode(token);
+            if (array != null && array.length > 0) {
+                String decodeString = new String(array);
+                String[] idSecretPair = decodeString.split(":");
+                if (idSecretPair != null && idSecretPair.length == 2) {
+                    Credential credential = new Credential();
+                    credential.setId(idSecretPair[0]);
+                    credential.setSecret(idSecretPair[1]);
+                    return credential;
+                }
+
+            }
+        } catch (Exception ex) {
+            throw new CredentialGenerationException
+                    ("Error occurred while decoding token ", ex);
+
+        }
+        return null;
+    }
+
+
+    public Credential decodeJWTToken(String token) {
+        try {
+            java.util.Base64.Decoder decoder = java.util.Base64.getUrlDecoder();
+            String[] parts = token.split("\\."); // split out the "parts" (header, payload and signature)
+
+            String headerJson = new String(decoder.decode(parts[0]));
+            String payloadJson = new String(decoder.decode(parts[1]));
+            String signatureJson = new String(decoder.decode(parts[2]));
+
+            ObjectMapper mapper = new ObjectMapper();
+            Map<String, Object> jsonMap = mapper.readValue(payloadJson, new TypeReference<Map<String, Object>>() {
+            });
+
+            Credential credential = new Credential();
+            credential.setId(jsonMap.get("azp").toString());
+            credential.setEmail(jsonMap.get("email").toString());
+            credential.setUsername(jsonMap.get("preferred_username").toString());
+
+            if (jsonMap.get("realm_access") != null) {
+                ObjectMapper reader = new ObjectMapper();
+                JsonNode node = reader.readValue(payloadJson, JsonNode.class);
+                JsonNode realmAccess = node.get("realm_access");
+                if (realmAccess instanceof JsonNode) {
+                    JsonNode jsonArray = (realmAccess).get("roles");
+                    if (jsonArray != null && jsonArray.isArray()) {
+
+                        jsonArray.forEach(json -> {
+                            if (json.asText().equals("admin")) {
+                                credential.setAdmin(true);
+                            }
+                        });
+                    }
+                }
+            }
+
+            return credential;
+        } catch (Exception ex) {
+            throw new CredentialGenerationException
+                    ("Error occurred while decoding token ", ex);
+
+        }
+
+    }
+
+    //TODO use UUID
+    private String generateRandomClientId(int length) {
+        StringBuilder returnValue = new StringBuilder(length);
+        for (int i = 0; i < length; i++) {
+            returnValue.append(ALPHABET.charAt(RANDOM.nextInt(ALPHABET.length())));
+        }
+        return new String(returnValue);
+    }
+
+    //TODO use UUID
+    private String generateSecret(int length) {
+        StringBuilder returnValue = new StringBuilder(length);
+        for (int i = 0; i < length; i++) {
+            returnValue.append(ALPHABET.charAt(RANDOM.nextInt(ALPHABET.length())));
+        }
+        return new String(returnValue);
+    }
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/exceptions/CredentialGenerationException.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/exceptions/CredentialGenerationException.java
new file mode 100644
index 0000000..56202be
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/exceptions/CredentialGenerationException.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.exceptions;
+
+public class CredentialGenerationException extends RuntimeException {
+    public CredentialGenerationException(String s, Exception exception) {
+    }
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/exceptions/MissingParameterException.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/exceptions/MissingParameterException.java
new file mode 100644
index 0000000..36abe39
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/exceptions/MissingParameterException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.exceptions;
+
+/**
+ * Missing Parameter
+ */
+public class MissingParameterException extends RuntimeException {
+
+   public MissingParameterException(String msg, Throwable e) {
+      super(msg,e);
+   }
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/Credential.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/Credential.java
new file mode 100644
index 0000000..3cc434c
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/Credential.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.model;
+
+/**
+ * Representation of Secret at Vault
+ */
+public class Credential {
+
+    private String id;
+    private String secret;
+    private String email;
+    private boolean superTenant;
+    private  boolean isAdmin;
+    private String username;
+    private String password;
+
+    public Credential(String id, String secret) {
+        this.id = id;
+        this.secret = secret;
+    }
+
+    public Credential() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getSecret() {
+        return secret;
+    }
+
+    public void setSecret(String secret) {
+        this.secret = secret;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public boolean isSuperTenant() {
+        return superTenant;
+    }
+
+    public void setSuperTenant(boolean superTenant) {
+        this.superTenant = superTenant;
+    }
+
+    public boolean isAdmin() {
+        return isAdmin;
+    }
+
+    public void setAdmin(boolean admin) {
+        isAdmin = admin;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/CredentialTypes.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/CredentialTypes.java
new file mode 100644
index 0000000..f8a0899
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/model/CredentialTypes.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.model;
+
+/**
+ * A list of all credential  generation types supported by custos
+ */
+public enum  CredentialTypes {
+    CUSTOS,
+    EXTERNAL,
+    AGENT
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/model/AgentCredentialEntity.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/model/AgentCredentialEntity.java
new file mode 100644
index 0000000..4891bf9
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/model/AgentCredentialEntity.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "agent_credentials")
+@EntityListeners(AuditingEntityListener.class)
+public class AgentCredentialEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String clientId;
+
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date issuedAt;
+
+    @Column(nullable = false)
+    private long clientSecretExpiredAt;
+
+
+    @Column(nullable = false)
+    private long ownerId;
+
+    @Column(nullable = false)
+    private String type;
+
+    @ManyToOne
+    @JoinColumn(name = "custos_credentials_id")
+    private CredentialEntity credentialEntity;
+
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public Date getIssuedAt() {
+        return issuedAt;
+    }
+
+    public void setIssuedAt(Date issuedAt) {
+        this.issuedAt = issuedAt;
+    }
+
+    public long getClientSecretExpiredAt() {
+        return clientSecretExpiredAt;
+    }
+
+    public void setClientSecretExpiredAt(long clientSecretExpiredAt) {
+        this.clientSecretExpiredAt = clientSecretExpiredAt;
+    }
+
+    public long getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(long ownerId) {
+        this.ownerId = ownerId;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public CredentialEntity getCredentialEntity() {
+        return credentialEntity;
+    }
+
+    public void setCredentialEntity(CredentialEntity credentialEntity) {
+        this.credentialEntity = credentialEntity;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/model/CredentialEntity.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/model/CredentialEntity.java
new file mode 100644
index 0000000..c0dd891
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/model/CredentialEntity.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.Set;
+
+@Entity
+@Table(name = "custos_credentials")
+@EntityListeners(AuditingEntityListener.class)
+public class CredentialEntity {
+
+    @Column(nullable = false)
+    private String clientId;
+
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date issuedAt;
+
+     @Column(nullable = false)
+    private long clientSecretExpiredAt;
+
+    @Id
+    @Column(nullable = false)
+    private long ownerId;
+
+     @Column(nullable = false)
+     private String type;
+
+    @OneToMany(mappedBy = "credentialEntity", cascade = CascadeType.ALL)
+    Set<AgentCredentialEntity> agentCredentialEntities;
+
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public Date getIssuedAt() {
+        return issuedAt;
+    }
+
+    public void setIssuedAt(Date issuedAt) {
+        this.issuedAt = issuedAt;
+    }
+
+    public long getClientSecretExpiredAt() {
+        return clientSecretExpiredAt;
+    }
+
+    public void setClientSecretExpiredAt(long clientSecretExpiredAt) {
+        this.clientSecretExpiredAt = clientSecretExpiredAt;
+    }
+
+    public long getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(long ownerId) {
+        this.ownerId = ownerId;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+
+    public Set<AgentCredentialEntity> getAgentCredentialEntities() {
+        return agentCredentialEntities;
+    }
+
+    public void setAgentCredentialEntities(Set<AgentCredentialEntity> agentCredentialEntities) {
+        this.agentCredentialEntities = agentCredentialEntities;
+    }
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/repository/AgentCredentialRepository.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/repository/AgentCredentialRepository.java
new file mode 100644
index 0000000..d7dc384
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/repository/AgentCredentialRepository.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.persistance.repository;
+
+import org.apache.custos.credential.store.persistance.model.AgentCredentialEntity;
+import org.apache.custos.credential.store.persistance.model.CredentialEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface AgentCredentialRepository extends JpaRepository<AgentCredentialEntity, Long> {
+
+    @Transactional
+    public AgentCredentialEntity findByClientIdAndOwnerId(String clientId, long ownerId);
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/repository/CredentialRepository.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/repository/CredentialRepository.java
new file mode 100644
index 0000000..10d0b40
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/persistance/repository/CredentialRepository.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.persistance.repository;
+
+import org.apache.custos.credential.store.persistance.model.CredentialEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface CredentialRepository extends JpaRepository<CredentialEntity, Long> {
+
+    @Transactional
+   public CredentialEntity findByClientId(String clientId);
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/service/CredentialStoreService.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/service/CredentialStoreService.java
new file mode 100644
index 0000000..cebe06b
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/service/CredentialStoreService.java
@@ -0,0 +1,1021 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.service;
+
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.core.services.commons.StatusUpdater;
+import org.apache.custos.core.services.commons.persistance.model.StatusEntity;
+import org.apache.custos.credential.store.credential.CredentialManager;
+import org.apache.custos.credential.store.model.Credential;
+import org.apache.custos.credential.store.model.CredentialTypes;
+import org.apache.custos.credential.store.persistance.model.AgentCredentialEntity;
+import org.apache.custos.credential.store.persistance.model.CredentialEntity;
+import org.apache.custos.credential.store.persistance.repository.AgentCredentialRepository;
+import org.apache.custos.credential.store.persistance.repository.CredentialRepository;
+import org.apache.custos.credential.store.service.CredentialStoreServiceGrpc.CredentialStoreServiceImplBase;
+import org.apache.custos.credential.store.utils.Operations;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.vault.core.VaultTemplate;
+import org.springframework.vault.support.VaultResponseSupport;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * This is responsible for vault operations
+ */
+@GRpcService
+public class CredentialStoreService extends CredentialStoreServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CredentialStoreService.class);
+
+    private static final String BASE_PATH = "/secret/";
+
+    @Autowired
+    private VaultTemplate vaultTemplate;
+
+    @Autowired
+    private StatusUpdater statusUpdater;
+
+    @Autowired
+    private CredentialManager credentialManager;
+
+    @Autowired
+    private CredentialRepository repository;
+
+    @Autowired
+    private AgentCredentialRepository agentCredentialRepository;
+
+    @Override
+    public void putCredential(CredentialMetadata request, StreamObserver<OperationStatus> responseObserver) {
+
+        try {
+            LOGGER.debug("Calling putSecret API for owner " + request.getOwnerId() + " with credentials Id "
+                    + request.getId() + " Secret " + request.getSecret());
+            String path = BASE_PATH + request.getOwnerId() + "/" + request.getType().name();
+            Credential credential = new Credential(request.getId(), request.getSecret());
+            vaultTemplate.write(path, credential);
+            VaultResponseSupport<Credential> response = vaultTemplate.read(path, Credential.class);
+            if (response != null && response.getData() != null && response.getData().getId() != null) {
+                OperationStatus secretStatus = OperationStatus.newBuilder().setState(true).build();
+
+                statusUpdater.updateStatus(Operations.PUT_CREDENTIAL.name(),
+                        org.apache.custos.core.services.commons.persistance.model.OperationStatus.SUCCESS,
+                        request.getOwnerId(),
+                        null);
+
+
+                responseObserver.onNext(secretStatus);
+                responseObserver.onCompleted();
+            } else {
+
+                String msg = "PutSecret operation failed for "
+                        + request.getOwnerId() + "with credentials Id "
+                        + request.getId() + " Secret " + request.getSecret() + " Type " + request.getType().name();
+                LOGGER.error(msg);
+
+                statusUpdater.updateStatus(Operations.PUT_CREDENTIAL.name(),
+                        org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                        request.getOwnerId(),
+                        null);
+
+                responseObserver.onError(Status.ABORTED.withDescription(msg).asRuntimeException());
+            }
+        } catch (Exception ex) {
+            String msg = "PutSecret operation failed for "
+                    + request.getOwnerId() + "with credentials Id "
+                    + request.getId() + " Secret " + request.getSecret() + " Type " + request.getType().name();
+            LOGGER.error(msg);
+
+            statusUpdater.updateStatus(Operations.PUT_CREDENTIAL.name(),
+                    org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                    request.getOwnerId(),
+                    null);
+
+            responseObserver.onError(Status.ABORTED.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getCredential(GetCredentialRequest request, StreamObserver<CredentialMetadata> responseObserver) {
+        try {
+            LOGGER.debug("Calling getSecret API for owner " + request.getOwnerId() + " for type " + request.getType());
+            String path = BASE_PATH + request.getOwnerId() + "/" + request.getType().name();
+            VaultResponseSupport<Credential> response = vaultTemplate.read(path, Credential.class);
+
+            if (response == null) {
+                String msg = "Cannot find credentials for "
+                        + request.getOwnerId() + " for type " + request.getType();
+                CredentialMetadata secret = CredentialMetadata.newBuilder().build();
+                responseObserver.onNext(secret);
+                responseObserver.onCompleted();
+                return;
+
+            }
+            Credential credential = response.getData();
+            CredentialMetadata.Builder secret = CredentialMetadata.newBuilder()
+                    .setSecret(credential.getSecret())
+                    .setId(credential.getId())
+                    .setOwnerId(request.getOwnerId());
+
+
+            if (request.getType() == Type.CUSTOS) {
+                Optional<CredentialEntity> entity = repository.findById(request.getOwnerId());
+                if (entity.isPresent()) {
+                    secret.setClientIdIssuedAt(entity.get().getIssuedAt().getTime());
+                    secret.setClientSecretExpiredAt(entity.get().getClientSecretExpiredAt());
+                }
+            }
+
+            responseObserver.onNext(secret.build());
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+
+            String msg = " operation failed for "
+                    + request.getOwnerId() + "with credentials Id "
+                    + request.getId() + " Type " + request.getType().name();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAllCredentials(GetAllCredentialsRequest request, StreamObserver<GetAllCredentialsResponse>
+            responseObserver) {
+        try {
+            LOGGER.debug("Calling getAllSecrets API for owner " + request.getOwnerId());
+
+            String subPath = BASE_PATH + request.getOwnerId();
+            List<String> paths = vaultTemplate.list(subPath);
+
+            List<CredentialMetadata> credentialMetadata = new ArrayList<>();
+
+            if (paths != null && !paths.isEmpty()) {
+                for (String key : paths) {
+                    if (isMainType(key)) {
+                        String path = subPath + "/" + key;
+                        VaultResponseSupport<Credential> crRe = vaultTemplate.read(path, Credential.class);
+                        CredentialMetadata metadata = convertToCredentialMetadata(crRe.getData(), request.getOwnerId(), key);
+                        credentialMetadata.add(metadata);
+                    }
+                }
+            }
+            GetAllCredentialsResponse response = GetAllCredentialsResponse.newBuilder()
+                    .addAllSecretList(credentialMetadata).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " operation failed for " + request.getOwnerId() + " " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteCredential(DeleteCredentialRequest request, StreamObserver<OperationStatus> responseObserver) {
+
+        try {
+
+            LOGGER.debug("Calling deleteSecret API for owner " + request.getOwnerId());
+
+
+            String subPath = BASE_PATH + request.getOwnerId() + (request.getType() != null ? "/" +
+                    request.getType().name() : "");
+
+            List<String> paths = vaultTemplate.list(subPath);
+
+            if (paths != null && !paths.isEmpty()) {
+                for (String key : paths) {
+                    String path = subPath + "/" + key;
+                    vaultTemplate.delete(path);
+
+                }
+            }
+
+            OperationStatus secretStatus = OperationStatus.newBuilder().setState(true).build();
+
+            statusUpdater.updateStatus(Operations.DELETE_CREDENTIAL.name(),
+                    org.apache.custos.core.services.commons.persistance.model.OperationStatus.SUCCESS,
+                    request.getOwnerId(),
+                    null);
+            responseObserver.onNext(secretStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " operation failed for " + request.getOwnerId();
+
+            statusUpdater.updateStatus(Operations.DELETE_CREDENTIAL.name(),
+                    org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                    request.getOwnerId(),
+                    null);
+
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getOperationMetadata(GetOperationsMetadataRequest request, StreamObserver<GetOperationsMetadataResponse> responseObserver) {
+        try {
+            LOGGER.debug("Calling getOperationMetadata API for traceId " + request.getTraceId());
+
+            List<OperationMetadata> metadata = new ArrayList<>();
+            List<StatusEntity> entities = statusUpdater.getOperationStatus(request.getTraceId());
+            if (entities == null || entities.size() > 0) {
+
+                for (StatusEntity statusEntity : entities) {
+                    OperationMetadata data = convertFromEntity(statusEntity);
+                    metadata.add(data);
+                }
+            }
+
+            GetOperationsMetadataResponse response = GetOperationsMetadataResponse
+                    .newBuilder()
+                    .addAllMetadata(metadata)
+                    .build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " operation failed for " + request.getTraceId();
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getNewCustosCredential(GetNewCustosCredentialRequest request, StreamObserver<CredentialMetadata> responseObserver) {
+        try {
+            LOGGER.debug("Generating custos credentials for  " + request.getOwnerId());
+
+            Credential credential = credentialManager.generateCredential(request.getOwnerId(), CredentialTypes.CUSTOS, 0);
+
+            String path = BASE_PATH + request.getOwnerId() + "/" + CredentialTypes.CUSTOS.name();
+
+            vaultTemplate.write(path, credential);
+
+            VaultResponseSupport<Credential> response = vaultTemplate.read(path, Credential.class);
+
+            if (response == null || response.getData() == null || response.getData().getId() == null) {
+                String msg = "Get new custos operation failed for "
+                        + request.getOwnerId();
+                LOGGER.error(msg);
+                statusUpdater.updateStatus(Operations.GENERATE_CUSTOS_CREDENTIAL.name(),
+                        org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                        request.getOwnerId(),
+                        null);
+
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            statusUpdater.updateStatus(Operations.GENERATE_CUSTOS_CREDENTIAL.name(),
+                    org.apache.custos.core.services.commons.persistance.model.OperationStatus.SUCCESS,
+                    request.getOwnerId(),
+                    null);
+
+            Optional<CredentialEntity> entity = repository.findById(request.getOwnerId());
+
+            if (entity.isEmpty()) {
+                String msg = "Credential is not persisted"
+                        + request.getOwnerId();
+                LOGGER.error(msg);
+                statusUpdater.updateStatus(Operations.GENERATE_CUSTOS_CREDENTIAL.name(),
+                        org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                        request.getOwnerId(),
+                        null);
+
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            CredentialEntity en = entity.get();
+            CredentialMetadata rep = CredentialMetadata
+                    .newBuilder()
+                    .setOwnerId(request.getOwnerId())
+                    .setSecret(credential.getSecret())
+                    .setClientIdIssuedAt(en.getIssuedAt().getTime())
+                    .setClientSecretExpiredAt(en.getClientSecretExpiredAt())
+                    .setId(credential.getId())
+                    .build();
+            responseObserver.onNext(rep);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " operation failed for " + request.getOwnerId();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getOwnerIdFromToken(TokenRequest request, StreamObserver<GetOwnerIdResponse> responseObserver) {
+        try {
+            LOGGER.debug("Get ownerId for    " + request.getToken());
+            String token = request.getToken();
+            Credential credential = credentialManager.decodeToken(token);
+
+            if (credential == null || credential.getId() == null) {
+                LOGGER.error("Invalid access token");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            CredentialEntity entity = repository.findByClientId(credential.getId());
+
+
+            if (entity != null) {
+                GetOwnerIdResponse response = GetOwnerIdResponse.
+                        newBuilder().setOwnerId(entity.getOwnerId()).build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            } else {
+                LOGGER.error("User not found");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = " operation failed ";
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getCustosCredentialFromToken(TokenRequest request, StreamObserver<CredentialMetadata> responseObserver) {
+        try {
+            LOGGER.debug("Get credential for    " + request.getToken());
+            String token = request.getToken();
+            Credential credential = credentialManager.decodeToken(token);
+
+            if (credential == null || credential.getId() == null) {
+                LOGGER.error("Invalid access token");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            CredentialEntity entity = repository.findByClientId(credential.getId());
+
+            if (entity == null) {
+                LOGGER.error("User not found");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            String path = BASE_PATH + entity.getOwnerId() + "/" + Type.CUSTOS.name();
+            VaultResponseSupport<Credential> response = vaultTemplate.read(path, Credential.class);
+
+            if (response == null || response.getData() == null || !response.getData().getSecret().equals(credential.getSecret())) {
+                String msg = "Invalid secret for id"
+                        + credential.getId();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            CredentialMetadata secret = CredentialMetadata.newBuilder()
+                    .setSecret(credential.getSecret())
+                    .setId(credential.getId())
+                    .setOwnerId(entity.getOwnerId())
+                    .setClientSecretExpiredAt(entity.getClientSecretExpiredAt())
+                    .setClientIdIssuedAt(entity.getIssuedAt().getTime())
+                    .setType(Type.CUSTOS).build();
+            responseObserver.onNext(secret);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " operation failed ";
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getCustosCredentialFromClientId(GetCredentialRequest request, StreamObserver<CredentialMetadata> responseObserver) {
+        try {
+            String clientId = request.getId();
+
+            CredentialEntity entity = repository.findByClientId(clientId);
+
+            if (entity == null) {
+                String msg = " Credentials not found for user " + clientId;
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            String path = BASE_PATH + entity.getOwnerId() + "/" + Type.CUSTOS.name();
+
+            VaultResponseSupport<Credential> response = vaultTemplate.read(path, Credential.class);
+
+            if (response == null || response.getData() == null) {
+                String msg = "Cannot find credentials for "
+                        + entity.getOwnerId() + " for type " + Type.CUSTOS.name();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            CredentialMetadata metadata = CredentialMetadata.newBuilder()
+                    .setSecret(response.getData().getSecret())
+                    .setId(request.getId())
+                    .setOwnerId(entity.getOwnerId())
+                    .setClientSecretExpiredAt(entity.getClientSecretExpiredAt())
+                    .setClientIdIssuedAt(entity.getIssuedAt().getTime())
+                    .setSuperTenant(response.getData().isSuperTenant())
+                    .setType(Type.CUSTOS).build();
+            responseObserver.onNext(metadata);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " Operation failed failed " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getAllCredentialsFromToken(TokenRequest request, StreamObserver<GetAllCredentialsResponse> responseObserver) {
+        try {
+            String token = request.getToken();
+            Credential credential = credentialManager.decodeToken(token);
+
+            if (credential == null || credential.getId() == null) {
+                LOGGER.error("Invalid access token");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            CredentialEntity entity = repository.findByClientId(credential.getId());
+
+            if (entity == null) {
+                LOGGER.error(" client not found");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            String subPath = BASE_PATH + entity.getOwnerId();
+
+            String validatingPath = BASE_PATH + entity.getOwnerId() + "/" + Type.CUSTOS.name();
+            VaultResponseSupport<Credential> validationResponse = vaultTemplate.read(validatingPath, Credential.class);
+
+            if (validationResponse == null || validationResponse.getData() == null || !validationResponse.getData().getSecret().equals(credential.getSecret())) {
+                String msg = "Invalid secret for id"
+                        + credential.getId();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            List<String> paths = vaultTemplate.list(subPath);
+
+            List<CredentialMetadata> credentialMetadata = new ArrayList<>();
+
+
+            if (paths != null && !paths.isEmpty()) {
+                for (String key : paths) {
+                    if (isMainType(key)) {
+                        String path = subPath + "/" + key;
+                        VaultResponseSupport<Credential> crRe = vaultTemplate.read(path, Credential.class);
+                        CredentialMetadata metadata = convertToCredentialMetadata(crRe.getData(), entity.getOwnerId(), key);
+
+
+                        if (key.equals(Type.CUSTOS)) {
+                            metadata = metadata.toBuilder()
+                                    .setClientIdIssuedAt(entity.getIssuedAt().getTime())
+                                    .setClientSecretExpiredAt(entity.getClientSecretExpiredAt())
+                                    .build();
+                        }
+                        credentialMetadata.add(metadata);
+                    }
+                }
+            }
+            GetAllCredentialsResponse response = GetAllCredentialsResponse.newBuilder()
+                    .addAllSecretList(credentialMetadata).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " Operation failed failed " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getBasicCredentials(TokenRequest request, StreamObserver<Credentials> responseObserver) {
+        try {
+
+            String token = request.getToken();
+            Credential credential = credentialManager.decodeToken(token);
+
+            if (credential == null || credential.getId() == null) {
+                LOGGER.error("Invalid access token");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            CredentialEntity entity = repository.findByClientId(credential.getId());
+
+            if (entity == null) {
+                LOGGER.error("User not found");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+            String subPath = BASE_PATH + entity.getOwnerId();
+            List<String> paths = vaultTemplate.list(subPath);
+
+
+            Credentials.Builder credentialsBuilder = Credentials.newBuilder();
+
+
+            if (entity == null) {
+                LOGGER.error("User not found");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+
+            if (paths != null && !paths.isEmpty()) {
+                for (String key : paths) {
+                    String path = subPath + "/" + key;
+                    VaultResponseSupport<Credential> crRe = vaultTemplate.read(path, Credential.class);
+                    if (key.equals(Type.CUSTOS)) {
+                        if (!crRe.getData().getSecret().equals(credential.getSecret())) {
+                            String msg = "Invalid secret for id"
+                                    + credential.getId();
+                            LOGGER.error(msg);
+                            responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+                            return;
+                        }
+
+                        credentialsBuilder.setCustosClientId(crRe.getData().getId())
+                                .setCustosClientSecret(crRe.getData().getSecret())
+                                .setCustosClientIdIssuedAt(entity.getIssuedAt().getTime())
+                                .setCustosClientSecretExpiredAt(entity.getClientSecretExpiredAt());
+
+                    } else if (key.equals(Type.IAM)) {
+                        credentialsBuilder.setIamClientId(crRe.getData().getId())
+                                .setIamClientSecret(crRe.getData().getSecret());
+
+
+                    } else if (key.equals(Type.CILOGON)) {
+
+                        credentialsBuilder.setCiLogonClientId(crRe.getData().getId())
+                                .setCiLogonClientSecret(crRe.getData().getSecret());
+
+                    }
+
+                }
+            }
+
+            Credentials credentials = credentialsBuilder.build();
+
+            responseObserver.onNext(credentials);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " Operation failed failed " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getAllCredentialsFromJWTToken(TokenRequest request, StreamObserver<GetAllCredentialsResponse> responseObserver) {
+        try {
+            String token = request.getToken();
+
+            Credential credential = credentialManager.decodeJWTToken(token);
+            if (credential == null || credential.getId() == null) {
+                LOGGER.error("Invalid access token");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            CredentialEntity entity = repository.findByClientId(credential.getId());
+
+            if (entity == null) {
+                LOGGER.error("User not found");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            String subPath = BASE_PATH + entity.getOwnerId();
+            List<String> paths = vaultTemplate.list(subPath);
+
+
+            List<CredentialMetadata> credentialMetadata = new ArrayList<>();
+
+            if (paths != null && !paths.isEmpty()) {
+                for (String key : paths) {
+                    if (isMainType(key)) {
+                        String path = subPath + "/" + key;
+                        VaultResponseSupport<Credential> crRe = vaultTemplate.read(path, Credential.class);
+                        CredentialMetadata metadata = convertToCredentialMetadata(crRe.getData(), entity.getOwnerId(), key);
+
+
+                        if (key.equals(Type.CUSTOS.name())) {
+
+                            metadata = metadata.toBuilder()
+                                    .setClientIdIssuedAt(entity.getIssuedAt().getTime())
+                                    .setClientSecretExpiredAt(entity.getClientSecretExpiredAt())
+                                    .setSuperAdmin(credential.isAdmin())
+                                    .setSuperTenant(crRe.getData().isSuperTenant())
+                                    .build();
+                        }
+                        credentialMetadata.add(metadata);
+                    }
+                }
+            }
+
+
+            GetAllCredentialsResponse response = GetAllCredentialsResponse.newBuilder()
+                    .addAllSecretList(credentialMetadata)
+                    .setRequesterUserEmail(credential.getEmail())
+                    .setRequesterUsername(credential.getUsername())
+                    .build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " Operation failed  " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getMasterCredentials(GetCredentialRequest request, StreamObserver<GetAllCredentialsResponse> responseObserver) {
+        try {
+
+            String subPath = BASE_PATH + "master";
+            List<String> paths = vaultTemplate.list(subPath);
+
+            List<CredentialMetadata> credentialMetadata = new ArrayList<>();
+
+
+            if (paths != null && !paths.isEmpty()) {
+                for (String key : paths) {
+                    if (isMainType(key)) {
+                        String path = subPath + "/" + key;
+                        VaultResponseSupport<Credential> crRe = vaultTemplate.read(path, Credential.class);
+                        CredentialMetadata metadata = convertToCredentialMetadata(crRe.getData(), 0, key);
+                        credentialMetadata.add(metadata);
+                    }
+                }
+            }
+            GetAllCredentialsResponse response = GetAllCredentialsResponse.newBuilder()
+                    .addAllSecretList(credentialMetadata).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " Operation failed  " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void createAgentCredential(CredentialMetadata request, StreamObserver<CredentialMetadata> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to createAgentCredential " + request.getOwnerId());
+
+            AgentCredentialEntity exEntity = agentCredentialRepository.findByClientIdAndOwnerId(request.getId(),
+                    request.getOwnerId());
+
+            if (exEntity != null) {
+                String msg = "Duplicate client Id " + request.getId() + " for "
+                        + request.getOwnerId();
+                LOGGER.error(msg);
+                statusUpdater.updateStatus(Operations.GENERATE_AGENT_CREDENTIAL.name(),
+                        org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                        request.getOwnerId(),
+                        null);
+
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            if (isMainType(request.getId())) {
+                String msg = "Prohibited agent Id  " + request.getId();
+                LOGGER.error(msg);
+                statusUpdater.updateStatus(Operations.GENERATE_AGENT_CREDENTIAL.name(),
+                        org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                        request.getOwnerId(),
+                        null);
+
+                responseObserver.onError(Status.INVALID_ARGUMENT.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            Credential credential = credentialManager.generateAgentCredential(request.getOwnerId(), request.getId(),
+                    CredentialTypes.AGENT, 0);
+
+            String path = BASE_PATH + request.getOwnerId() + "/" + request.getId();
+
+            vaultTemplate.write(path, credential);
+
+            VaultResponseSupport<Credential> response = vaultTemplate.read(path, Credential.class);
+
+            if (response == null || response.getData() == null || response.getData().getId() == null) {
+                String msg = "Get new agent credentials operation failed of "
+                        + request.getOwnerId();
+                LOGGER.error(msg);
+                statusUpdater.updateStatus(Operations.GENERATE_AGENT_CREDENTIAL.name(),
+                        org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                        request.getOwnerId(),
+                        null);
+
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            AgentCredentialEntity entity = agentCredentialRepository.findByClientIdAndOwnerId(request.getId(),
+                    request.getOwnerId());
+
+            if (entity == null) {
+                String msg = "Credential is not persisted of "
+                        + request.getId() + "at tenant " + request.getOwnerId();
+                LOGGER.error(msg);
+                statusUpdater.updateStatus(Operations.GENERATE_AGENT_CREDENTIAL.name(),
+                        org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                        request.getOwnerId(),
+                        null);
+
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            statusUpdater.updateStatus(Operations.GENERATE_AGENT_CREDENTIAL.name(),
+                    org.apache.custos.core.services.commons.persistance.model.OperationStatus.SUCCESS,
+                    request.getOwnerId(),
+                    null);
+
+            CredentialMetadata rep = CredentialMetadata
+                    .newBuilder()
+                    .setOwnerId(request.getOwnerId())
+                    .setSecret(credential.getSecret())
+                    .setClientIdIssuedAt(entity.getIssuedAt().getTime())
+                    .setClientSecretExpiredAt(entity.getClientSecretExpiredAt())
+                    .setId(credential.getId())
+                    .setInternalSec(credential.getPassword())
+                    .build();
+            responseObserver.onNext(rep);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " Create Agent credential operation is failed  " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteAgentCredential(CredentialMetadata request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug(" Request received for deleteAgentCredential for  " + request.getId() + " at tenant "
+                    + request.getOwnerId());
+
+            String subPath = BASE_PATH + request.getOwnerId() + "/" + request.getId();
+
+            List<String> paths = vaultTemplate.list(subPath);
+
+            if (paths != null && !paths.isEmpty()) {
+                for (String key : paths) {
+                    String path = subPath + "/" + key;
+                    vaultTemplate.delete(path);
+
+                }
+            }
+
+            AgentCredentialEntity entity = agentCredentialRepository.findByClientIdAndOwnerId(request.getId(), request.getOwnerId());
+
+            if (entity != null) {
+                agentCredentialRepository.delete(entity);
+            }
+
+            OperationStatus secretStatus = OperationStatus.newBuilder().setState(true).build();
+
+            statusUpdater.updateStatus(Operations.DELETE_AGENT_CREDENTIAL.name(),
+                    org.apache.custos.core.services.commons.persistance.model.OperationStatus.SUCCESS,
+                    request.getOwnerId(),
+                    null);
+            responseObserver.onNext(secretStatus);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " Delete agent credential failed  " + ex;
+            LOGGER.error(msg);
+            statusUpdater.updateStatus(Operations.DELETE_AGENT_CREDENTIAL.name(),
+                    org.apache.custos.core.services.commons.persistance.model.OperationStatus.FAILED,
+                    request.getOwnerId(),
+                    null);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAgentCredential(GetCredentialRequest request, StreamObserver<CredentialMetadata> responseObserver) {
+        try {
+            LOGGER.debug(" Request received for getAgentCredential " + request.getOwnerId());
+
+            String clientId = request.getId();
+
+            AgentCredentialEntity entity = agentCredentialRepository.findByClientIdAndOwnerId(request.getId(),
+                    request.getOwnerId());
+
+            if (entity == null) {
+                String msg = " Credentials not found for user " + clientId;
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            String path = BASE_PATH + entity.getOwnerId() + "/" + request.getId();
+
+            VaultResponseSupport<Credential> response = vaultTemplate.read(path, Credential.class);
+
+            if (response == null || response.getData() == null) {
+                String msg = "Cannot find credentials for "
+                        + entity.getClientId() + " at tenant " + request.getOwnerId();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            CredentialMetadata metadata = CredentialMetadata.newBuilder()
+                    .setSecret(response.getData().getSecret())
+                    .setId(request.getId())
+                    .setInternalSec(response.getData().getPassword())
+                    .setOwnerId(entity.getOwnerId())
+                    .setType(Type.AGENT).build();
+            responseObserver.onNext(metadata);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Operation failed  " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getCredentialByAgentBasicAuth(TokenRequest request, StreamObserver<GetAllCredentialsResponse> responseObserver) {
+        try {
+            LOGGER.debug(" Request received for getCredentialByAgentBasicAuth ");
+
+            String token = request.getToken();
+
+            Credential credential = credentialManager.decodeToken(token);
+
+            if (credential == null || credential.getId() == null) {
+                LOGGER.error("Invalid access token");
+                responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            CredentialEntity exEntity = repository.findByClientId(request.getParentClientId());
+
+            if (exEntity != null) {
+
+                AgentCredentialEntity entity = agentCredentialRepository.findByClientIdAndOwnerId(credential.getId(),
+                        exEntity.getOwnerId());
+
+                if (entity == null) {
+                    LOGGER.error("Agent not found");
+                    responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
+                    return;
+                }
+                String subPath = BASE_PATH + entity.getOwnerId();
+                List<String> paths = vaultTemplate.list(subPath);
+
+                List<CredentialMetadata> metadataList = new ArrayList<>();
+
+
+                if (paths != null && !paths.isEmpty()) {
+                    for (String key : paths) {
+                        String path = subPath + "/" + key;
+                        VaultResponseSupport<Credential> crRe = vaultTemplate.read(path, Credential.class);
+
+                        if (isMainType(key)) {
+                            CredentialMetadata metadata = convertToCredentialMetadata(crRe.getData(), entity.getOwnerId(), key);
+                            metadataList.add(metadata);
+
+                        } else if (key.equals(credential.getId())) {
+                            if (!crRe.getData().getSecret().equals(credential.getSecret())) {
+                                String msg = "Invalid secret for id"
+                                        + credential.getId();
+                                LOGGER.error(msg);
+                                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+                                return;
+                            }
+                            CredentialMetadata metadata = CredentialMetadata
+                                    .newBuilder()
+                                    .setType(Type.AGENT)
+                                    .setId(credential.getId())
+                                    .setSecret(crRe.getData().getSecret())
+                                    .setInternalSec(crRe.getData().getPassword())
+                                    .build();
+                            metadataList.add(metadata);
+                        }
+                    }
+                }
+
+                GetAllCredentialsResponse response = GetAllCredentialsResponse
+                        .newBuilder()
+                        .addAllSecretList(metadataList)
+                        .build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+
+            } else {
+                String msg = " Cannot find a valid  client Id for tenant ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            }
+        } catch (Exception ex) {
+            String msg = " Operation failed  " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+
+
+
+    private OperationMetadata convertFromEntity(StatusEntity entity) {
+        return OperationMetadata.newBuilder()
+                .setEvent(entity.getEvent())
+                .setStatus(entity.getState())
+                .setPerformedBy(entity.getPerformedBy())
+                .setTimeStamp(entity.getTime().toString()).build();
+    }
+
+
+    private CredentialMetadata convertToCredentialMetadata(Credential credential, long ownerId, String type) {
+
+        return CredentialMetadata.newBuilder()
+                .setOwnerId(ownerId)
+                .setType(Type.valueOf(type))
+                .setId(credential.getId())
+                .setSuperTenant(credential.isSuperTenant())
+                .setSecret(credential.getSecret())
+                .build();
+    }
+
+
+    private boolean isMainType(String str) {
+        for (Type type : Type.values()) {
+            if (type.name().equalsIgnoreCase(str))
+                return true;
+        }
+        return false;
+    }
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/utils/Operations.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/utils/Operations.java
new file mode 100644
index 0000000..359e7e6
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/utils/Operations.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.utils;
+
+public enum Operations {
+    PUT_CREDENTIAL,
+    DELETE_CREDENTIAL,
+    GENERATE_CUSTOS_CREDENTIAL,
+    GENERATE_AGENT_CREDENTIAL,
+    DELETE_AGENT_CREDENTIAL
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/validator/InputValidator.java b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/validator/InputValidator.java
new file mode 100644
index 0000000..cea136f
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/java/org/apache/custos/credential/store/validator/InputValidator.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.credential.store.validator;
+
+
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.credential.store.exceptions.MissingParameterException;
+import org.apache.custos.credential.store.service.*;
+
+/**
+ * This class validates the  requests
+ */
+public class InputValidator implements Validator {
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "putCredential":
+                validatePutCredential(obj, methodName);
+                break;
+            case "deleteCredential":
+                validateDeleteCredential(obj, methodName);
+                break;
+            case "getCredential":
+                validateGetCredential(obj, methodName);
+                break;
+            case "getAllCredentials":
+                validateGetAllCredentials(obj, methodName);
+                break;
+            case "getNewCustosCredential":
+                validateGetNewCustosCredential(obj, methodName);
+                break;
+            case "getOwnerIdFromToken":
+            case "getCredentialFromToken":
+            case "getAllCredentialsFromJWTToken":
+            case "getAllCredentialsFromToken":
+            case "getCustosCredentialFromToken":
+                validateTokenRequest(obj, methodName);
+                break;
+            case "getCredentialFromClientId":
+                validateGetCredentialFromClientId(obj, methodName);
+                break;
+            default:
+        }
+    }
+
+    private boolean validatePutCredential(Object obj, String method) {
+        if (obj instanceof CredentialMetadata) {
+            CredentialMetadata metadata = (CredentialMetadata) obj;
+
+            if (metadata.getOwnerId() == 0) {
+                throw new MissingParameterException("OwnerId cannot be null at " + method, null);
+            }
+
+            if (metadata.getId() == null || metadata.getId().trim().equals("")) {
+                throw new MissingParameterException("Id cannot be null at " + method, null);
+            }
+
+            if (metadata.getSecret() == null || metadata.getSecret().trim().equals("")) {
+                throw new MissingParameterException("Secret cannot be null at " + method, null);
+            }
+
+            if (metadata.getType() == null) {
+                throw new MissingParameterException("Type cannot be null at " + method, null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + method);
+        }
+        return true;
+    }
+
+    private boolean validateDeleteCredential(Object obj, String method) {
+        if (obj instanceof DeleteCredentialRequest) {
+            DeleteCredentialRequest metadata = (DeleteCredentialRequest) obj;
+            if (metadata.getOwnerId() == 0) {
+                throw new MissingParameterException("OwnerId cannot be null at " + method, null);
+            }
+
+
+            if (metadata.getType() == null) {
+                throw new MissingParameterException("Type cannot be null at " + method, null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + method);
+        }
+        return true;
+    }
+
+    private boolean validateGetCredential(Object obj, String method) {
+        if (obj instanceof GetCredentialRequest) {
+            GetCredentialRequest metadata = (GetCredentialRequest) obj;
+            if (metadata.getOwnerId() == 0) {
+                throw new MissingParameterException("OwnerId cannot be null at " + method, null);
+            }
+
+            if (metadata.getType() == null) {
+                throw new MissingParameterException("Type cannot be null at " + method, null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + method);
+        }
+        return true;
+
+    }
+
+    private boolean validateGetNewCustosCredential(Object obj, String method) {
+        if (obj instanceof GetNewCustosCredentialRequest) {
+            GetNewCustosCredentialRequest metadata = (GetNewCustosCredentialRequest) obj;
+            if (metadata.getOwnerId() == 0) {
+                throw new MissingParameterException("OwnerId cannot be null at " + method, null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + method);
+        }
+        return true;
+
+    }
+
+    private boolean validateTokenRequest(Object obj, String method) {
+        if (obj instanceof TokenRequest) {
+            TokenRequest metadata = (TokenRequest) obj;
+            if (metadata.getToken() == null || metadata.getToken().trim().equals("")) {
+                throw new MissingParameterException("Token cannot be null at " + method, null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + method);
+        }
+        return true;
+
+    }
+
+    private boolean validateGetAllCredentials(Object obj, String method) {
+        if (obj instanceof GetAllCredentialsRequest) {
+            GetAllCredentialsRequest request = (GetAllCredentialsRequest) obj;
+            if (request.getOwnerId() == 0) {
+                throw new MissingParameterException("OwnerId cannot be null at " + method, null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + method);
+        }
+        return true;
+
+    }
+
+    private boolean validateGetCredentialFromClientId(Object obj, String method) {
+        if (obj instanceof GetCredentialRequest) {
+            GetCredentialRequest request = (GetCredentialRequest) obj;
+            if (request.getId() == null || request.getId().equals("")) {
+                throw new MissingParameterException("Client Id cannot be null at " + method, null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + method);
+        }
+        return true;
+    }
+
+}
diff --git a/custos-core-services/credential-store-core-service/src/main/proto/CredentialStoreService.proto b/custos-core-services/credential-store-core-service/src/main/proto/CredentialStoreService.proto
new file mode 100644
index 0000000..ecb8315
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/proto/CredentialStoreService.proto
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.credential.store.service;
+
+enum Type {
+    CUSTOS = 0;
+    IAM = 1;
+    CILOGON = 2;
+    INDIVIDUAL = 3;
+    AGENT_CLIENT = 4;
+    AGENT = 5;
+}
+
+message CredentialMetadata {
+    int64 ownerId = 1;
+    string id = 2;
+    string secret = 3;
+    int64 clientSecretExpiredAt = 4;
+    int64 clientIdIssuedAt = 5;
+    Type type = 6;
+    bool super_tenant = 7;
+    bool super_admin = 8;
+    string internal_sec = 11;
+}
+
+message GetCredentialRequest {
+    int64 ownerId = 1;
+    string id = 2;
+    Type type = 3;
+}
+
+message GetAllCredentialsRequest {
+    int64 ownerId = 1;
+}
+
+message GetAllCredentialsResponse {
+    repeated CredentialMetadata secretList = 1;
+    string requesterUserEmail = 2;
+    string requesterUsername = 3;
+}
+
+message OperationStatus {
+    bool state = 1;
+}
+
+message DeleteCredentialRequest {
+    int64 ownerId = 1;
+    Type type = 2;
+}
+
+message GetOperationsMetadataRequest {
+    int64 traceId = 1;
+}
+
+message OperationMetadata {
+    string event = 1;
+    string status = 2;
+    string timeStamp = 3;
+    string performedBy = 4;
+}
+message GetOperationsMetadataResponse {
+    repeated OperationMetadata metadata = 1;
+}
+
+message GetNewCustosCredentialRequest {
+    int64 ownerId = 1;
+    string performedBy = 2;
+}
+
+message GetNewCustosCredentialResponse {
+    string clientId = 1;
+    string clientSecret = 2;
+}
+
+message TokenRequest {
+    string token = 1;
+    string parentClientId = 2;
+}
+
+message GetOwnerIdResponse {
+    int64 ownerId = 2;
+}
+
+message Credentials {
+    string iam_client_id = 1;
+    string iam_client_secret = 2;
+    string ci_logon_client_id = 3;
+    string ci_logon_client_secret = 4;
+    string custos_client_id = 5;
+    string custos_client_secret = 6;
+    double custos_client_id_issued_at = 7;
+    double custos_client_secret_expired_at = 8;
+}
+
+
+
+service CredentialStoreService {
+    rpc putCredential (CredentialMetadata) returns (OperationStatus);
+    rpc deleteCredential (DeleteCredentialRequest) returns (OperationStatus);
+    rpc getCredential (GetCredentialRequest) returns (CredentialMetadata);
+    rpc getAllCredentials (GetAllCredentialsRequest) returns (GetAllCredentialsResponse);
+    rpc getOperationMetadata (GetOperationsMetadataRequest) returns (GetOperationsMetadataResponse);
+    rpc getNewCustosCredential (GetNewCustosCredentialRequest) returns (CredentialMetadata);
+    rpc getOwnerIdFromToken (TokenRequest) returns (GetOwnerIdResponse);
+    rpc getCustosCredentialFromToken (TokenRequest) returns (CredentialMetadata);
+    rpc getCustosCredentialFromClientId (GetCredentialRequest) returns (CredentialMetadata);
+    rpc getAllCredentialsFromToken (TokenRequest) returns (GetAllCredentialsResponse);
+    rpc getMasterCredentials (GetCredentialRequest) returns (GetAllCredentialsResponse);
+    rpc getAllCredentialsFromJWTToken (TokenRequest) returns (GetAllCredentialsResponse);
+    rpc getBasicCredentials (TokenRequest) returns (Credentials);
+
+
+    rpc createAgentCredential (CredentialMetadata) returns (CredentialMetadata);
+    rpc getAgentCredential (GetCredentialRequest) returns (CredentialMetadata);
+    rpc deleteAgentCredential (CredentialMetadata) returns (OperationStatus);
+    rpc getCredentialByAgentBasicAuth (TokenRequest) returns (GetAllCredentialsResponse);
+    rpc getCredentialByAgentJWTToken (TokenRequest) returns (GetAllCredentialsResponse);
+
+
+}
\ No newline at end of file
diff --git a/custos-core-services/credential-store-core-service/src/main/resources/application.properties b/custos-core-services/credential-store-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..a26a7d1
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/resources/application.properties
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=credentialStoreCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_credential_store?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
\ No newline at end of file
diff --git a/custos-core-services/credential-store-core-service/src/main/resources/bootstrap.properties b/custos-core-services/credential-store-core-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..3d6e403
--- /dev/null
+++ b/custos-core-services/credential-store-core-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,26 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.vault.token=vault_token
+spring.cloud.vault.scheme=http
+spring.cloud.vault.host=vault.custos.scigap.org
+spring.cloud.vault.port=30249
+spring.cloud.vault.uri=http://vault.custos.scigap.org:30249
+spring.cloud.vault.authentication=token
+
diff --git a/custos-core-services/custos-core-services-commons/pom.xml b/custos-core-services/custos-core-services-commons/pom.xml
new file mode 100644
index 0000000..1135ea2
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/pom.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-core-services-commons</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/ServiceInterceptor.java b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/ServiceInterceptor.java
new file mode 100644
index 0000000..c249af7
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/ServiceInterceptor.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.core.services.commons;
+
+import io.grpc.*;
+import org.apache.custos.core.services.commons.exceptions.MissingParameterException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class intercepts incoming requests and forwarding for validation
+ */
+public class ServiceInterceptor implements ServerInterceptor {
+
+    private final Logger LOGGER = LoggerFactory.getLogger(ServiceInterceptor.class);
+
+    private Validator validator;
+
+    public ServiceInterceptor(Validator validator) {
+        this.validator = validator;
+    }
+
+    @Override
+    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall,
+                                                                 Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
+
+        String fullMethod = serverCall.getMethodDescriptor().getFullMethodName();
+        String methodName = fullMethod.split("/")[1];
+
+        LOGGER.debug("Calling method : " + serverCall.getMethodDescriptor().getFullMethodName());
+
+        return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(serverCallHandler.startCall(serverCall, metadata)) {
+            @Override
+            public void onMessage(ReqT message) {
+                try {
+                    validator.validate(methodName, message);
+                    super.onMessage(message);
+                } catch (Exception ex) {
+                    String msg = "Error while validating method " + methodName + " " + ex.getMessage();
+                    LOGGER.error(msg);
+                    if (ex instanceof MissingParameterException) {
+                        serverCall.close(Status.FAILED_PRECONDITION.withDescription(msg), metadata);
+                    } else {
+                        serverCall.close(Status.UNKNOWN.withDescription(msg), metadata);
+                    }
+                }
+            }
+
+            @Override
+            public void onHalfClose() {
+                try {
+                    super.onHalfClose();
+                } catch (IllegalStateException e) {
+                    LOGGER.debug(e.getMessage());
+                } catch (Exception e) {
+                    String msg = "Error while validating method " + methodName + " " + e.getMessage();
+                    LOGGER.error(msg);
+                    serverCall.close(Status.UNKNOWN.withDescription(msg), metadata);
+                }
+            }
+        };
+    }
+
+
+}
diff --git a/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/StatusUpdater.java b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/StatusUpdater.java
new file mode 100644
index 0000000..a0ecf4a
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/StatusUpdater.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.core.services.commons;
+
+import org.apache.custos.core.services.commons.persistance.model.OperationStatus;
+import org.apache.custos.core.services.commons.persistance.model.StatusEntity;
+import org.apache.custos.core.services.commons.persistance.repository.StatusUpdaterRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+
+@Component
+public class StatusUpdater {
+
+    private final Logger LOGGER = LoggerFactory.getLogger(StatusUpdater.class);
+
+    @Autowired
+    private StatusUpdaterRepository repository;
+
+
+    public void updateStatus(String method, OperationStatus status, long traceId, String performedBy) {
+        try {
+            StatusEntity statusEntity = new StatusEntity();
+            statusEntity.setEvent(method);
+            statusEntity.setState(status.name());
+            statusEntity.setTraceId(traceId);
+            statusEntity.setPerformedBy(performedBy);
+            repository.save(statusEntity);
+        } catch (Exception ex) {
+            LOGGER.error("Status update failed for event " + method + " and traceId " + traceId);
+        }
+
+    }
+
+    public List<StatusEntity> getOperationStatus(long traceId) {
+       return repository.findAllByTraceId(traceId);
+    }
+
+}
diff --git a/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/Validator.java b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/Validator.java
new file mode 100644
index 0000000..074d498
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/Validator.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.core.services.commons;
+
+public interface Validator {
+
+    public void validate (String methodName, Object body);
+}
diff --git a/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/exceptions/MissingParameterException.java b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/exceptions/MissingParameterException.java
new file mode 100644
index 0000000..5424abf
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/exceptions/MissingParameterException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.core.services.commons.exceptions;
+
+/**
+ * Missing Parameter
+ */
+public class MissingParameterException extends RuntimeException {
+
+   public MissingParameterException(String msg, Throwable e) {
+      super(msg,e);
+   }
+}
diff --git a/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/persistance/model/OperationStatus.java b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/persistance/model/OperationStatus.java
new file mode 100644
index 0000000..8342c87
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/persistance/model/OperationStatus.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.core.services.commons.persistance.model;
+
+public enum OperationStatus {
+
+    SUCCESS,
+    FAILED
+}
diff --git a/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/persistance/model/StatusEntity.java b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/persistance/model/StatusEntity.java
new file mode 100644
index 0000000..fb268c6
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/persistance/model/StatusEntity.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.core.services.commons.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Captured and stores Keycloak events
+ */
+@Entity
+@Table(name = "event_metadata")
+@EntityListeners(AuditingEntityListener.class)
+public class StatusEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String event;
+
+    @Column(nullable = false)
+    private String state;
+
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date time;
+
+    @Column(nullable = false)
+    private Long traceId;
+
+
+    private String performedBy;
+
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getEvent() {
+        return event;
+    }
+
+    public void setEvent(String event) {
+        this.event = event;
+    }
+
+    public Date getTime() {
+        return time;
+    }
+
+    public void setTime(Date time) {
+        this.time = time;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+
+    public Long getTraceId() {
+        return traceId;
+    }
+
+    public void setTraceId(Long traceId) {
+        this.traceId = traceId;
+    }
+
+    public String getPerformedBy() {
+        return performedBy;
+    }
+
+    public void setPerformedBy(String performedBy) {
+        this.performedBy = performedBy;
+    }
+}
diff --git a/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/persistance/repository/StatusUpdaterRepository.java b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/persistance/repository/StatusUpdaterRepository.java
new file mode 100644
index 0000000..fc96854
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/persistance/repository/StatusUpdaterRepository.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.core.services.commons.persistance.repository;
+
+import org.apache.custos.core.services.commons.persistance.model.StatusEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+public interface StatusUpdaterRepository extends JpaRepository<StatusEntity, Long> {
+
+    @Transactional
+    public List<StatusEntity> findAllByTraceId(long traceId);
+}
diff --git a/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/util/Constants.java b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/util/Constants.java
new file mode 100644
index 0000000..4be0d49
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/util/Constants.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.core.services.commons.util;
+
+public final class Constants {
+
+    public static final String  CUSTOS_REALM_AGENT  = "custos-realm-agent";
+    public static  final String AGENT_CLIENT = "agent-client";
+    public static final String  OWNER_ID = "custos-ownerId";
+    public static final String DESCRIPTION = "custos-description";
+
+}
diff --git a/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/util/MethodNameExtractor.java b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/util/MethodNameExtractor.java
new file mode 100644
index 0000000..53ba403
--- /dev/null
+++ b/custos-core-services/custos-core-services-commons/src/main/java/org/apache/custos/core/services/commons/util/MethodNameExtractor.java
@@ -0,0 +1,9 @@
+package org.apache.custos.core.services.commons.util;
+
+public class MethodNameExtractor {
+
+    public static String getMethodName (String methodName) {
+        String[] names = methodName.split("/");
+        return  names[names.length - 1];
+    }
+}
diff --git a/custos-core-services/custos-logging/Dockerfile b/custos-core-services/custos-logging/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/custos-logging/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/custos-logging/pom.xml b/custos-core-services/custos-logging/pom.xml
new file mode 100644
index 0000000..5bf6aff
--- /dev/null
+++ b/custos-core-services/custos-logging/pom.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-logging</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/custos-logging/src/main/helm/.helmignore b/custos-core-services/custos-logging/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/custos-logging/src/main/helm/Chart.yaml b/custos-core-services/custos-logging/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..2005e82
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of custos Logging service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/custos-logging/src/main/helm/templates/NOTES.txt b/custos-core-services/custos-logging/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/custos-logging/src/main/helm/templates/_helpers.tpl b/custos-core-services/custos-logging/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/custos-logging/src/main/helm/templates/deployment.yaml b/custos-core-services/custos-logging/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..31e54a6
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,64 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/custos-logging/src/main/helm/templates/ingress.yaml b/custos-core-services/custos-logging/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/custos-logging/src/main/helm/templates/service.yaml b/custos-core-services/custos-logging/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/custos-logging/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/custos-logging/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/custos-logging/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/custos-logging/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/custos-logging/src/main/helm/values.yaml b/custos-core-services/custos-logging/src/main/helm/values.yaml
new file mode 100644
index 0000000..93eb74d
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/helm/values.yaml
@@ -0,0 +1,78 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/LoggingServiceInitializer.java b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/LoggingServiceInitializer.java
new file mode 100644
index 0000000..555ed7f
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/LoggingServiceInitializer.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import validator.InputValidator;
+
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableJpaRepositories(basePackages = "org.apache.custos")
+@ComponentScan(basePackages = "org.apache.custos")
+@EntityScan(basePackages = "org.apache.custos")
+public class LoggingServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(LoggingServiceInitializer.class, args);
+    }
+
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator){
+        return new ServiceInterceptor(validator);
+    }
+}
diff --git a/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/mapper/LogEventMapper.java b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/mapper/LogEventMapper.java
new file mode 100644
index 0000000..aa2bdc5
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/mapper/LogEventMapper.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging.mapper;
+
+import org.apache.custos.logging.service.LogEvent;
+
+public class LogEventMapper {
+
+
+    public static LogEvent transform(org.apache.custos.logging.persistance.model.LogEvent logEvent) {
+
+        LogEvent event = LogEvent
+                .newBuilder()
+                .setTenantId(logEvent.getTenantId())
+                .setClientId(logEvent.getClientId())
+                .setCreatedTime(logEvent.getCreatedTime())
+                .setServiceName(logEvent.getServiceName())
+                .setEventType(logEvent.getEventType())
+                .setExternalIp(logEvent.getRemoteIp())
+                .setUsername(logEvent.getUsername() != null ? logEvent.getUsername() : "")
+                .build();
+
+        return event;
+    }
+
+    public static org.apache.custos.logging.persistance.model.LogEvent transform(LogEvent logEvent) {
+
+        org.apache.custos.logging.persistance.model.LogEvent event = new
+                org.apache.custos.logging.persistance.model.LogEvent();
+
+        event.setClientId(logEvent.getClientId());
+        event.setTenantId(logEvent.getTenantId());
+        event.setCreatedTime(logEvent.getCreatedTime());
+        event.setRemoteIp(logEvent.getExternalIp());
+        event.setEventType(logEvent.getEventType());
+        event.setServiceName(logEvent.getServiceName());
+        event.setUsername(logEvent.getUsername());
+        return event;
+
+    }
+
+}
diff --git a/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/model/LogEvent.java b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/model/LogEvent.java
new file mode 100644
index 0000000..dc66f00
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/model/LogEvent.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging.persistance.model;
+
+
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+
+/**
+ * Represents Log event
+ */
+@Entity
+@Table(name = "log_events")
+@EntityListeners(AuditingEntityListener.class)
+public class LogEvent {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private long tenantId;
+
+    @Column(nullable = false)
+    private String serviceName;
+
+    @Column(nullable = false)
+    private String eventType;
+
+    @Column(nullable = false)
+    private long createdTime;
+
+    @Column(nullable = false)
+    private String clientId;
+
+    @Column
+    private String username;
+
+    @Column
+    private String remoteIp;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public void setServiceName(String serviceName) {
+        this.serviceName = serviceName;
+    }
+
+    public String getEventType() {
+        return eventType;
+    }
+
+    public void setEventType(String eventType) {
+        this.eventType = eventType;
+    }
+
+    public long getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getRemoteIp() {
+        return remoteIp;
+    }
+
+    public void setRemoteIp(String remoteIp) {
+        this.remoteIp = remoteIp;
+    }
+}
diff --git a/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/model/LoggingEnabledStatus.java b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/model/LoggingEnabledStatus.java
new file mode 100644
index 0000000..67f5b85
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/model/LoggingEnabledStatus.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging.persistance.model;
+
+
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+
+/**
+ * Represents Logging enabled status for tenant
+ */
+@Entity
+@Table(name = "logging_enabled_status")
+@EntityListeners(AuditingEntityListener.class)
+public class LoggingEnabledStatus {
+
+    @Id
+    @Column(nullable = false)
+    private long tenantId;
+
+    @Column(nullable = false)
+    private boolean status;
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public boolean isStatus() {
+        return status;
+    }
+
+    public void setStatus(boolean status) {
+        this.status = status;
+    }
+}
diff --git a/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LogEventRepo.java b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LogEventRepo.java
new file mode 100644
index 0000000..14d7aad
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LogEventRepo.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging.persistance.repository;
+
+import org.apache.custos.logging.persistance.model.LogEvent;
+import org.apache.custos.logging.service.LogEventRequest;
+
+import java.util.List;
+
+public interface LogEventRepo {
+
+    List<LogEvent> searchEvents (LogEventRequest request);
+}
diff --git a/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LogEventRepoImpl.java b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LogEventRepoImpl.java
new file mode 100644
index 0000000..982f3ba
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LogEventRepoImpl.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging.persistance.repository;
+
+import org.apache.custos.logging.persistance.model.LogEvent;
+import org.apache.custos.logging.service.LogEventRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Repository
+public class LogEventRepoImpl implements LogEventRepo {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(LogEventRepoImpl.class);
+
+    @PersistenceContext
+    EntityManager entityManager;
+
+
+    @Override
+    public List<LogEvent> searchEvents(LogEventRequest request) {
+        Map<String, Object> valueMap = new HashMap<>();
+
+        String query = createSQLQuery(request, valueMap);
+
+        Query q = entityManager.createNativeQuery(query, LogEvent.class);
+        for (String key : valueMap.keySet()) {
+            q.setParameter(key, valueMap.get(key));
+        }
+
+        return q.getResultList();
+    }
+
+
+    private String createSQLQuery(LogEventRequest logEventRequest, Map<String, Object> valueMap) {
+
+        String query = "SELECT * FROM log_events E WHERE ";
+
+
+        if (logEventRequest.getTenantId() != 0) {
+
+            query = query + "E.tenant_id = :" + "tenant_id" + " AND ";
+
+            valueMap.put("tenant_id", logEventRequest.getTenantId());
+
+        }
+
+        if (logEventRequest.getClientId() != null && !logEventRequest.getClientId().equals("")) {
+
+            query = query + "E.client_id = :" + "client_id" + " AND ";
+
+            valueMap.put("client_id", logEventRequest.getClientId());
+
+        }
+
+        if (logEventRequest.getServiceName() != null && !logEventRequest.getServiceName().equals("")) {
+
+            query = query + "E.service_name = :" + "service_name" + " AND ";
+
+            valueMap.put("service_name", logEventRequest.getServiceName());
+
+        }
+
+        if (logEventRequest.getEventType() != null && !logEventRequest.getEventType().equals("")) {
+
+            query = query + "E.event_type = :" + "event_type" + " AND ";
+
+            valueMap.put("event_type", logEventRequest.getEventType());
+
+        }
+
+        if (logEventRequest.getRemoteIp() != null && !logEventRequest.getRemoteIp().equals("")) {
+
+            query = query + "E.remote_ip = :" + "remote_ip" + " AND ";
+
+            valueMap.put("remote_ip", logEventRequest.getEventType());
+
+        }
+
+        if (logEventRequest.getUsername() != null && !logEventRequest.getUsername().equals("")) {
+
+            query = query + "E.username = :" + "username" + " AND ";
+
+            valueMap.put("username", logEventRequest.getEventType());
+
+        }
+
+        if (logEventRequest.getStartTime() > 0) {
+
+            query = query + "E.created_time >= :" + "created_time" + " AND ";
+
+            valueMap.put("created_time", logEventRequest.getStartTime());
+
+        }
+
+        if (logEventRequest.getEndTime() > 0) {
+
+            query = query + "E.created_time < :" + "created_time" + " AND ";
+
+            valueMap.put("created_time", logEventRequest.getEndTime());
+
+        }
+
+        query = query.substring(0, query.length() - 5);
+
+        query = query + " ORDER BY E.created_time DESC ";
+
+        if (logEventRequest.getOffset() >= 0 && logEventRequest.getLimit() > 0) {
+            query = query + " LIMIT " + ":limit" + " OFFSET " + ":offset";
+            valueMap.put("limit", logEventRequest.getLimit());
+            valueMap.put("offset", logEventRequest.getOffset());
+        }
+
+        LOGGER.info("Query ####" + query);
+
+
+        return query;
+
+    }
+}
diff --git a/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LogEventRepository.java b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LogEventRepository.java
new file mode 100644
index 0000000..87f933d
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LogEventRepository.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging.persistance.repository;
+
+import org.apache.custos.logging.persistance.model.LogEvent;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface LogEventRepository extends JpaRepository<LogEvent, Long>, LogEventRepo {
+
+
+}
diff --git a/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LoggingEnabledStatusRepository.java b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LoggingEnabledStatusRepository.java
new file mode 100644
index 0000000..837b1cb
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/persistance/repository/LoggingEnabledStatusRepository.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging.persistance.repository;
+
+import org.apache.custos.logging.persistance.model.LoggingEnabledStatus;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface LoggingEnabledStatusRepository extends JpaRepository<LoggingEnabledStatus, Long> {
+
+}
diff --git a/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/service/LoggingService.java b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/service/LoggingService.java
new file mode 100644
index 0000000..e2f27c4
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/org/apache/custos/logging/service/LoggingService.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.logging.service;
+
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.logging.mapper.LogEventMapper;
+import org.apache.custos.logging.persistance.model.LoggingEnabledStatus;
+import org.apache.custos.logging.persistance.repository.LogEventRepository;
+import org.apache.custos.logging.persistance.repository.LoggingEnabledStatusRepository;
+import org.apache.custos.logging.service.LoggingServiceGrpc.LoggingServiceImplBase;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@GRpcService
+public class LoggingService extends LoggingServiceImplBase {
+    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingService.class);
+
+    @Autowired
+    private LoggingEnabledStatusRepository loggingEnabledStatusRepository;
+
+    @Autowired
+    private LogEventRepository logEventRepository;
+
+
+    @Override
+    public void addLogEvent(org.apache.custos.logging.service.LogEvent request,
+                            StreamObserver<org.apache.custos.logging.service.Status> responseObserver) {
+        try {
+
+            logEventRepository.save(LogEventMapper.transform(request));
+
+            org.apache.custos.logging.service.Status status =
+                    org.apache.custos.logging.service.Status.newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while adding logging event " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getLogEvents(org.apache.custos.logging.service.LogEventRequest request,
+                             StreamObserver<org.apache.custos.logging.service.LogEvents> responseObserver) {
+        try {
+
+            List<org.apache.custos.logging.persistance.model.LogEvent> logEvents =
+                    logEventRepository.searchEvents(request);
+
+            List<org.apache.custos.logging.service.LogEvent> logEventList = new ArrayList<>();
+
+            if (logEvents != null && logEvents.size() > 0) {
+                for (org.apache.custos.logging.persistance.model.LogEvent logEvent : logEvents) {
+                    logEventList.add(LogEventMapper.transform(logEvent));
+                }
+            }
+            org.apache.custos.logging.service.LogEvents logs =
+                    org.apache.custos.logging.service.LogEvents.newBuilder().addAllEvents(logEventList).build();
+            responseObserver.onNext(logs);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching log events " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void isLogEnabled(org.apache.custos.logging.service.LoggingConfigurationRequest request,
+                             StreamObserver<org.apache.custos.logging.service.Status> responseObserver) {
+        try {
+            Optional<LoggingEnabledStatus> loggingEnabledStatus = loggingEnabledStatusRepository.
+                    findById(request.getTenantId());
+
+            boolean status = false;
+
+            if (loggingEnabledStatus.isPresent()) {
+                LoggingEnabledStatus stat = loggingEnabledStatus.get();
+                status = stat.isStatus();
+            }
+
+            org.apache.custos.logging.service.Status res = org.apache.custos.logging.service.Status
+                    .newBuilder()
+                    .setStatus(status)
+                    .build();
+
+            responseObserver.onNext(res);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while checking logging is enabled " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void enable(org.apache.custos.logging.service.LoggingConfigurationRequest request,
+                       StreamObserver<org.apache.custos.logging.service.Status> responseObserver) {
+        try {
+
+            Optional<LoggingEnabledStatus> loggingEnabledStatus = loggingEnabledStatusRepository.
+                    findById(request.getTenantId());
+
+            if (loggingEnabledStatus.isEmpty()) {
+                LoggingEnabledStatus status = new LoggingEnabledStatus();
+                status.setStatus(true);
+                status.setTenantId(request.getTenantId());
+                loggingEnabledStatusRepository.save(status);
+            }
+
+            org.apache.custos.logging.service.Status status = org.apache.custos.logging.service.Status
+                    .newBuilder()
+                    .setStatus(true)
+                    .build();
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while logs are enabled " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+}
diff --git a/custos-core-services/custos-logging/src/main/java/validator/InputValidator.java b/custos-core-services/custos-logging/src/main/java/validator/InputValidator.java
new file mode 100644
index 0000000..7dc3585
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/java/validator/InputValidator.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package validator;
+
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.core.services.commons.exceptions.MissingParameterException;
+import org.apache.custos.logging.service.LogEvent;
+import org.apache.custos.logging.service.LogEventRequest;
+import org.apache.custos.logging.service.LoggingConfigurationRequest;
+
+
+/**
+ * This class validates the  requests
+ */
+public class InputValidator implements Validator {
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "addLogEvent":
+                validateAddLogEvent(methodName, obj);
+                break;
+
+            case "getLogEvents":
+                validateGetLogEvents(methodName, obj);
+                break;
+            case "isLogEnabled":
+                validateIsLogEnabled(methodName, obj);
+                break;
+            case "enable":
+                validateEnable(methodName, obj);
+                break;
+        }
+
+    }
+
+
+    private boolean validateAddLogEvent(String methodName, Object obj) {
+        if (obj instanceof LogEvent) {
+            LogEvent entityTypeRequest = (LogEvent) obj;
+            if (entityTypeRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+            if (entityTypeRequest.getClientId() == null || entityTypeRequest.getClientId().equals("")) {
+                throw new MissingParameterException("Client Id not found ", null);
+            }
+            if (entityTypeRequest.getServiceName() == null || entityTypeRequest.getServiceName().equals("")) {
+                throw new MissingParameterException("Service name  not found ", null);
+            }
+
+            if (entityTypeRequest.getEventType() == null || entityTypeRequest.getEventType().equals("")) {
+                throw new MissingParameterException("Event type  not found ", null);
+            }
+
+            if (entityTypeRequest.getExternalIp() == null || entityTypeRequest.getExternalIp().equals("")) {
+                throw new MissingParameterException("External Ip  not found ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateGetLogEvents(String methodName, Object obj) {
+        if (obj instanceof LogEventRequest) {
+            LogEventRequest entityTypeRequest = (LogEventRequest) obj;
+            if (entityTypeRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateIsLogEnabled(String methodName, Object obj) {
+        if (obj instanceof LoggingConfigurationRequest) {
+            LoggingConfigurationRequest entityTypeRequest = (LoggingConfigurationRequest) obj;
+            if (entityTypeRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateEnable(String methodName, Object obj) {
+        if (obj instanceof LoggingConfigurationRequest) {
+            LoggingConfigurationRequest entityTypeRequest = (LoggingConfigurationRequest) obj;
+            if (entityTypeRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+
+}
diff --git a/custos-core-services/custos-logging/src/main/proto/LoggingService.proto b/custos-core-services/custos-logging/src/main/proto/LoggingService.proto
new file mode 100644
index 0000000..889ca3d
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/proto/LoggingService.proto
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.logging.service;
+
+import "google/protobuf/empty.proto";
+
+
+message LogEvent {
+    int64 created_time = 1;
+    string service_name = 2;
+    string event_type = 3;
+    string username = 4;
+    string client_id = 5;
+    int64 tenant_id = 6;
+    string external_ip = 7;
+}
+
+message Status {
+    bool status = 1;
+}
+
+message LogEventRequest {
+    int64 tenant_id = 1;
+    int64 start_time = 2;
+    int64 end_time = 3;
+    string client_id = 4;
+    string username = 5;
+    string remote_ip = 6;
+    string service_name = 7;
+    string event_type = 8;
+    int32 offset = 9;
+    int32 limit = 10;
+}
+
+message LogEvents {
+    repeated LogEvent events = 1;
+}
+
+message LoggingConfigurationRequest {
+    int64 tenant_id = 1;
+    string client_id = 2;
+}
+
+
+service LoggingService {
+
+    rpc addLogEvent(LogEvent) returns (Status);
+
+    rpc getLogEvents(LogEventRequest) returns (LogEvents);
+
+    rpc isLogEnabled(LoggingConfigurationRequest) returns(Status);
+
+    rpc enable(LoggingConfigurationRequest) returns (Status);
+
+}
\ No newline at end of file
diff --git a/custos-core-services/custos-logging/src/main/resources/application.properties b/custos-core-services/custos-logging/src/main/resources/application.properties
new file mode 100644
index 0000000..2711f34
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/resources/application.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=loggingCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_logging?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
\ No newline at end of file
diff --git a/custos-core-services/custos-logging/src/main/resources/bootstrap.properties b/custos-core-services/custos-logging/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..fd0bbe0
--- /dev/null
+++ b/custos-core-services/custos-logging/src/main/resources/bootstrap.properties
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+spring.profiles.active:default
\ No newline at end of file
diff --git a/custos-core-services/federated-authentication-core-service/Dockerfile b/custos-core-services/federated-authentication-core-service/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/federated-authentication-core-service/pom.xml b/custos-core-services/federated-authentication-core-service/pom.xml
new file mode 100644
index 0000000..fcfba00
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/pom.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>federeted-authentication-core-service</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-federated-services-clients</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/.helmignore b/custos-core-services/federated-authentication-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/Chart.yaml b/custos-core-services/federated-authentication-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..edc47eb
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of custos Federarted Authentication service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..31e54a6
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,64 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/templates/service.yaml b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/federated-authentication-core-service/src/main/helm/values.yaml b/custos-core-services/federated-authentication-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..93eb74d
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/helm/values.yaml
@@ -0,0 +1,78 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/FederatedAuthenticationServiceInitializer.java b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/FederatedAuthenticationServiceInitializer.java
new file mode 100644
index 0000000..68fce77
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/FederatedAuthenticationServiceInitializer.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.apache.custos.federated.authentication.validator.InputValidator;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableJpaRepositories(basePackages = "org.apache.custos")
+@ComponentScan(basePackages = {"org.apache.custos.federated.authentication",
+        "org.apache.custos.federated.services.clients.cilogon", "org.apache.custos.core.services.commons"})
+@EntityScan(basePackages = "org.apache.custos")
+public class FederatedAuthenticationServiceInitializer {
+
+    public static void main(String[] args) {
+        SpringApplication.run(FederatedAuthenticationServiceInitializer.class,args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator){
+        return new ServiceInterceptor(validator);
+    }
+}
+
diff --git a/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/exceptions/FederatedAuthenticationServiceException.java b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/exceptions/FederatedAuthenticationServiceException.java
new file mode 100644
index 0000000..d03f4e3
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/exceptions/FederatedAuthenticationServiceException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication.exceptions;
+
+/**
+ * Wraps all the runtime exceptions captured during communication with IAM Server
+ */
+public class FederatedAuthenticationServiceException extends RuntimeException {
+
+    public FederatedAuthenticationServiceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/exceptions/MissingParameterException.java b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/exceptions/MissingParameterException.java
new file mode 100644
index 0000000..1e07851
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/exceptions/MissingParameterException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication.exceptions;
+
+/**
+ * Missing Parameter
+ */
+public class MissingParameterException extends RuntimeException {
+
+   public MissingParameterException(String msg, Throwable e) {
+      super(msg,e);
+   }
+}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/mapper/ModelMapper.java b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/mapper/ModelMapper.java
new file mode 100644
index 0000000..3dbb046
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/mapper/ModelMapper.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication.mapper;
+
+import org.apache.custos.federated.authentication.persistance.model.CILogonInstitution;
+import org.apache.custos.federated.authentication.service.Institution;
+
+public class ModelMapper {
+
+    public static CILogonInstitution convert(long tenantId, String institutionId, String type, String performedBy) {
+
+
+        String id = institutionId + "@" + tenantId;
+
+        CILogonInstitution ciLogonInstitution = new CILogonInstitution();
+        ciLogonInstitution.setId(id);
+        ciLogonInstitution.setInstitutionId(institutionId);
+        ciLogonInstitution.setTenantId(tenantId);
+        ciLogonInstitution.setType(type);
+        if (performedBy != null && !performedBy.equals("")) {
+            ciLogonInstitution.setCreatedBy(performedBy);
+        }
+
+        return ciLogonInstitution;
+
+    }
+
+
+    public static Institution convert(CILogonInstitution cache) {
+
+        Institution.Builder msg = Institution.newBuilder();
+
+        msg.setEntityId(cache.getInstitutionId());
+
+
+        return msg.build();
+    }
+
+
+    public static Institution convert(org.apache.custos.federated.services.clients.cilogon.CILogonInstitution ciLogonInstitution) {
+
+        Institution.Builder msg = Institution.newBuilder();
+
+        msg.setEntityId(ciLogonInstitution.getEntityId());
+        msg.setDisplayName(ciLogonInstitution.getDisplayName());
+        msg.setOrganizationName(ciLogonInstitution.getOrganizationName());
+        msg.setRandS(ciLogonInstitution.isRandS());
+        return msg.build();
+
+    }
+}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/persistance/model/CILogonInstitution.java b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/persistance/model/CILogonInstitution.java
new file mode 100644
index 0000000..fe77b95
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/persistance/model/CILogonInstitution.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Keeps track of whitelisted and blacklisted institutions
+ */
+@Entity
+@Table(name = "cilogon_institution_cache")
+@EntityListeners(AuditingEntityListener.class)
+public class CILogonInstitution {
+
+    @Id
+    private String id;
+
+    @Column(nullable = false)
+    private long tenantId;
+
+    @Column(nullable = false)
+    private String type;
+
+    @Column(nullable = false)
+    private String institutionId;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedAt;
+
+    private String createdBy;
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getInstitutionId() {
+        return institutionId;
+    }
+
+    public void setInstitutionId(String institutionId) {
+        this.institutionId = institutionId;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLastModifiedAt() {
+        return lastModifiedAt;
+    }
+
+    public void setLastModifiedAt(Date lastModifiedAt) {
+        this.lastModifiedAt = lastModifiedAt;
+    }
+
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(String createdBy) {
+        this.createdBy = createdBy;
+    }
+}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/persistance/repository/CiLogonInstitutionCacheRepository.java b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/persistance/repository/CiLogonInstitutionCacheRepository.java
new file mode 100644
index 0000000..561a4a2
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/persistance/repository/CiLogonInstitutionCacheRepository.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication.persistance.repository;
+
+import org.apache.custos.federated.authentication.persistance.model.CILogonInstitution;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface CiLogonInstitutionCacheRepository extends JpaRepository<CILogonInstitution, String> {
+
+    public List<CILogonInstitution> findAllByTenantIdAndType(long tenantId, String type);
+
+}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/service/FederatedAuthenticationService.java b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/service/FederatedAuthenticationService.java
new file mode 100644
index 0000000..8b5754c
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/service/FederatedAuthenticationService.java
@@ -0,0 +1,458 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication.service;
+
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.core.services.commons.StatusUpdater;
+import org.apache.custos.core.services.commons.persistance.model.OperationStatus;
+import org.apache.custos.core.services.commons.persistance.model.StatusEntity;
+import org.apache.custos.federated.authentication.exceptions.FederatedAuthenticationServiceException;
+import org.apache.custos.federated.authentication.mapper.ModelMapper;
+import org.apache.custos.federated.authentication.persistance.model.CILogonInstitution;
+import org.apache.custos.federated.authentication.persistance.repository.CiLogonInstitutionCacheRepository;
+import org.apache.custos.federated.authentication.service.FederatedAuthenticationServiceGrpc.FederatedAuthenticationServiceImplBase;
+import org.apache.custos.federated.authentication.utils.Operations;
+import org.apache.custos.federated.services.clients.cilogon.CILogonClient;
+import org.apache.custos.federated.services.clients.cilogon.CILogonResponse;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@GRpcService
+public class FederatedAuthenticationService extends FederatedAuthenticationServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(FederatedAuthenticationService.class);
+
+    @Autowired
+    private CILogonClient ciLogonClient;
+
+    @Autowired
+    private StatusUpdater statusUpdater;
+
+    @Autowired
+    private CiLogonInstitutionCacheRepository institutionRespository;
+
+    @Override
+    public void addClient(ClientMetadata request, StreamObserver<RegisterClientResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addClient for " + request.getTenantId());
+
+            if (request.getClientId() != null && !request.getClientId().trim().equals("")) {
+
+                try {
+                    ciLogonClient.deleteClient(request.getClientId());
+                } catch (Exception ex) {
+                    LOGGER.debug("Error occurred while deleting client " + request.getClientId());
+                }
+            }
+
+            String[] scopes = request.getScopeList() != null ?
+                    request.getScopeList().toArray(new String[request.getScopeCount()]) : new String[0];
+            String contact = request.getContactsList() != null ? request.getContacts(0) : null;
+
+
+            CILogonResponse response = ciLogonClient.registerClient(request.getTenantName(),
+                    request.getRedirectURIsList().toArray(new String[request.getRedirectURIsCount()]),
+                    request.getComment(),
+                    scopes,
+                    request.getTenantURI(),
+                    contact);
+
+            statusUpdater.updateStatus(Operations.ADD_CLIENT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            RegisterClientResponse registerClientResponse = RegisterClientResponse.newBuilder()
+                    .setClientId(response.getClientId())
+                    .setClientSecret(response.getClientSecret())
+                    .setClientSecretExpiresAt(response.getClientSecretExpiredAt())
+                    .setClientRegistrationUri(response.getRegistrationClientURI())
+                    .setClientIdIssuedAt(response.getClientIdIssuedAt()).build();
+
+            responseObserver.onNext(registerClientResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during addClient" + ex;
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(Operations.ADD_CLIENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            FederatedAuthenticationServiceException exception = new FederatedAuthenticationServiceException(msg, ex);
+            responseObserver.onError(exception);
+        }
+    }
+
+    @Override
+    public void updateClient(ClientMetadata request, StreamObserver<Empty> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateClient for " + request.getTenantId());
+            String[] scopes = request.getScopeList() != null ?
+                    request.getScopeList().toArray(new String[request.getScopeCount()]) : new String[0];
+            String contact = request.getContactsList() != null ? request.getContacts(0) : null;
+
+            ciLogonClient.updateClient(request.getClientId(), request.getTenantName(),
+                    request.getRedirectURIsList().toArray(new String[request.getRedirectURIsCount()]),
+                    request.getComment(),
+                    scopes,
+                    request.getTenantURI(),
+                    contact);
+
+            statusUpdater.updateStatus(Operations.UPDATE_CLIENT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            Empty empty = Empty.newBuilder().build();
+
+            responseObserver.onNext(empty);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during updateClient" + ex;
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(Operations.UPDATE_CLIENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            FederatedAuthenticationServiceException exception = new FederatedAuthenticationServiceException(msg, ex);
+            responseObserver.onError(exception);
+        }
+    }
+
+    @Override
+    public void getClient(GetClientRequest request, StreamObserver<GetClientResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getClient for " + request.getTenantId());
+
+            CILogonResponse response = ciLogonClient.getClient(request.getClientId());
+            GetClientResponse getClientResponse = GetClientResponse.newBuilder()
+                    .setClientId(response.getClientId())
+                    .setClientName(response.getClientName())
+                    .addAllRedirectURIs(Arrays.asList(response.getRedirectURIs()))
+                    .addAllScope(Arrays.asList(response.getScope()))
+                    .setComment(response.getComment())
+                    .setClientIdIssuedAt(response.getClientIdIssuedAt())
+                    .setClientRegistrationUri(response.getRegistrationClientURI())
+                    .setClientSecretExpiresAt(response.getClientSecretExpiredAt())
+                    .setClientSecret(response.getClientSecret())
+                    .addAllGrantTypes(Arrays.asList(response.getGrantTypes()))
+                    .build();
+
+            responseObserver.onNext(getClientResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during getClient" + ex;
+            LOGGER.error(msg, ex);
+            FederatedAuthenticationServiceException exception = new FederatedAuthenticationServiceException(msg, ex);
+            responseObserver.onError(exception);
+        }
+    }
+
+    @Override
+    public void deleteClient(DeleteClientRequest request, StreamObserver<Empty> responseObserver) {
+
+        try {
+            LOGGER.debug("Request received to deleteClient for " + request.getTenantId());
+
+            ciLogonClient.deleteClient(request.getClientId());
+
+            statusUpdater.updateStatus(Operations.DELETE_CLIENT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            Empty empty = Empty.newBuilder().build();
+
+            responseObserver.onNext(empty);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during deleteClient" + ex;
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(Operations.DELETE_CLIENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            FederatedAuthenticationServiceException exception = new FederatedAuthenticationServiceException(msg, ex);
+            responseObserver.onError(exception);
+        }
+    }
+
+    @Override
+    public void getOperationMetadata(GetOperationsMetadataRequest request, StreamObserver<GetOperationsMetadataResponse> responseObserver) {
+        try {
+            LOGGER.debug("Calling getOperationMetadata API for traceId " + request.getTraceId());
+
+            List<OperationMetadata> metadata = new ArrayList<>();
+            List<StatusEntity> entities = statusUpdater.getOperationStatus(request.getTraceId());
+            if (entities == null || entities.size() > 0) {
+
+                for (StatusEntity statusEntity : entities) {
+                    OperationMetadata data = convertFromEntity(statusEntity);
+                    metadata.add(data);
+                }
+            }
+
+            GetOperationsMetadataResponse response = GetOperationsMetadataResponse
+                    .newBuilder()
+                    .addAllMetadata(metadata)
+                    .build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            FederatedAuthenticationServiceException failedException = new FederatedAuthenticationServiceException(" operation failed for "
+                    + request.getTraceId(), ex);
+            responseObserver.onError(failedException);
+        }
+    }
+
+
+    @Override
+    public void addToCache(CacheManipulationRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Calling addToCache API for tenantId " + request.getTenantId());
+
+
+            long tenantId = request.getTenantId();
+
+            List<String> ids = request.getInstitutionIdsList();
+
+            InstitutionCacheType type = request.getType();
+
+            List<CILogonInstitution> ciLogonInstitutions = new ArrayList<>();
+
+            ids.forEach(id -> {
+                ciLogonInstitutions.add(ModelMapper.convert(tenantId, id, type.name(), request.getPerformedBy()));
+
+            });
+
+
+            for (CILogonInstitution ciLogonInstitution : ciLogonInstitutions) {
+
+                Optional<CILogonInstitution> optionalCILogonInstitution =
+                        institutionRespository.findById(ciLogonInstitution.getId());
+
+                if (optionalCILogonInstitution.isPresent()) {
+                    String msg = " Duplicate entry with Id  " + ciLogonInstitution.getInstitutionId();
+                    LOGGER.error(msg);
+                    responseObserver.onError(io.grpc.Status.ALREADY_EXISTS.withDescription(msg).asRuntimeException());
+                    return;
+                }
+
+            }
+
+
+            institutionRespository.saveAll(ciLogonInstitutions);
+
+            Status status = Status.newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Error at federated authentication core service " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeFromCache(CacheManipulationRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Calling removeFromCache API for tenantId" + request.getTenantId());
+            long tenantId = request.getTenantId();
+
+            List<String> ids = request.getInstitutionIdsList();
+
+            List<CILogonInstitution> ciLogonInstitutions = new ArrayList<>();
+
+            ids.forEach(id -> {
+
+                String savedId = id + "@" + tenantId;
+
+                Optional<CILogonInstitution> ciLogonList = institutionRespository.findById(savedId);
+
+                if (ciLogonList.isPresent()) {
+                    ciLogonInstitutions.add(ciLogonList.get());
+                }
+
+
+            });
+
+            institutionRespository.deleteAll(ciLogonInstitutions);
+
+            Status status = Status.newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Error at federated authentication core service " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getFromCache(CacheManipulationRequest request, StreamObserver<GetInstitutionsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Calling getFromCache API for tenantId " + request.getTenantId());
+
+
+            long tenant = request.getTenantId();
+
+            String type = request.getType().name();
+
+            List<CILogonInstitution> institutions = institutionRespository.findAllByTenantIdAndType(tenant, type);
+
+            List<Institution> institutionList = new ArrayList<>();
+
+            org.apache.custos.federated.services.clients.cilogon.CILogonInstitution[] ciLogonInstitutions =
+                    ciLogonClient.getInstitutions();
+
+            if (institutions != null && !institutions.isEmpty()) {
+
+                for (CILogonInstitution institution : institutions) {
+
+                    for (org.apache.custos.federated.services.clients.cilogon.CILogonInstitution
+                            ciLogonInstitution : ciLogonInstitutions) {
+                        if (ciLogonInstitution.getEntityId().equals(institution.getInstitutionId())) {
+                            institutionList.add(ModelMapper.convert(ciLogonInstitution));
+                        }
+                    }
+
+                }
+            }
+
+            GetInstitutionsResponse response = GetInstitutionsResponse.
+                    newBuilder().addAllInstitutions(institutionList).build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Error at federated authentication core service " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getInstitutions(CacheManipulationRequest request, StreamObserver<GetInstitutionsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Calling getInstitutions API for tenantId " + request.getTenantId());
+
+            long tenant = request.getTenantId();
+
+
+            List<CILogonInstitution> institutions = institutionRespository.findAllByTenantIdAndType(tenant, InstitutionCacheType.WHITELIST.name());
+
+            List<CILogonInstitution> backListedInstituions = institutionRespository.findAllByTenantIdAndType(tenant, InstitutionCacheType.BACKLIST.name());
+
+
+            org.apache.custos.federated.services.clients.cilogon.CILogonInstitution[] ciLogonInstitutions =
+                    ciLogonClient.getInstitutions();
+
+            List<org.apache.custos.federated.services.clients.cilogon.CILogonInstitution> selectedLists = new ArrayList<>();
+
+            if (institutions.isEmpty() && backListedInstituions.isEmpty()) {
+
+                selectedLists.addAll(Arrays.asList(ciLogonInstitutions));
+
+            } else if (!institutions.isEmpty()) {
+
+
+                for (org.apache.custos.federated.services.clients.cilogon.CILogonInstitution ciLogonInstitution : ciLogonInstitutions) {
+
+                    institutions.forEach(it -> {
+
+                        if (it.getInstitutionId().equals(ciLogonInstitution.getEntityId()) &&
+                                it.getType().equals(InstitutionCacheType.WHITELIST.name())) {
+                            selectedLists.add(ciLogonInstitution);
+                        }
+                    });
+
+                }
+
+            } else {
+
+                for (org.apache.custos.federated.services.clients.cilogon.CILogonInstitution ciLogonInstitution : ciLogonInstitutions) {
+
+                    AtomicBoolean doNotAdd = new AtomicBoolean(false);
+                    for (CILogonInstitution it : backListedInstituions) {
+
+                        if (it.getInstitutionId().equals(ciLogonInstitution.getEntityId())) {
+                            doNotAdd.set(true);
+                            break;
+
+                        }
+                    }
+
+                    if (!doNotAdd.get()) {
+                        selectedLists.add(ciLogonInstitution);
+                    }
+
+                }
+            }
+
+
+            List<Institution> institutionList = new ArrayList<>();
+
+            selectedLists.forEach(sl -> {
+
+                institutionList.add(ModelMapper.convert(sl));
+
+            });
+
+            GetInstitutionsResponse response = GetInstitutionsResponse
+                    .newBuilder().addAllInstitutions(institutionList).build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Error at federated authentication core service " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    private OperationMetadata convertFromEntity(StatusEntity entity) {
+        return OperationMetadata.newBuilder()
+                .setEvent(entity.getEvent())
+                .setStatus(entity.getState())
+                .setPerformedBy(entity.getPerformedBy())
+                .setTimeStamp(entity.getTime().toString()).build();
+    }
+
+}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/utils/Operations.java b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/utils/Operations.java
new file mode 100644
index 0000000..43256de
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/utils/Operations.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication.utils;
+
+/**
+ * Includes operations associated with keycloak
+ */
+public  enum Operations {
+
+    ADD_CLIENT,
+    DELETE_CLIENT,
+    UPDATE_CLIENT
+
+}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/validator/InputValidator.java b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/validator/InputValidator.java
new file mode 100644
index 0000000..e39fa27
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/java/org/apache/custos/federated/authentication/validator/InputValidator.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.authentication.validator;
+
+
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.federated.authentication.exceptions.MissingParameterException;
+import org.apache.custos.federated.authentication.service.CacheManipulationRequest;
+import org.apache.custos.federated.authentication.service.ClientMetadata;
+import org.apache.custos.federated.authentication.service.DeleteClientRequest;
+import org.apache.custos.federated.authentication.service.GetClientRequest;
+
+/**
+ * This class validates the  requests
+ */
+public class InputValidator implements Validator {
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "addClient":
+            case "updateClient":
+                validateClientMetadata(obj, methodName);
+                break;
+            case "getClient":
+                validateGetClientRequest(obj);
+                break;
+            case "deleteClient":
+                validateDeleteClientRequest(obj);
+                break;
+            case "addToCache":
+                validateAddToCache(obj, methodName);
+                break;
+            case "removeFromCache":
+                validateRemoveToCache(obj, methodName);
+                break;
+            case "getFromCache":
+                validateGetFromCache(obj, methodName);
+                break;
+            case "getInstitutions":
+                validateGetFromCache(obj, methodName);
+                break;
+            default:
+        }
+    }
+
+    private boolean validateClientMetadata(Object obj, String method) {
+        if (obj instanceof ClientMetadata) {
+            ClientMetadata metadata = (ClientMetadata) obj;
+            if (metadata.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (metadata.getTenantName() == null || metadata.getTenantName().trim().equals("")) {
+                throw new MissingParameterException("Tenant name should not be null", null);
+            }
+
+            if (metadata.getRedirectURIsList() == null || metadata.getRedirectURIsCount() == 0) {
+                throw new MissingParameterException("RedirectURIs should not be null", null);
+            }
+            if (metadata.getComment() == null || metadata.getComment().trim().equals("")) {
+                throw new MissingParameterException("Comment should not be null", null);
+            }
+
+            if (metadata.getPerformedBy() == null || metadata.getPerformedBy().trim().equals("")) {
+                throw new MissingParameterException("Performed by should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + method);
+        }
+        return true;
+    }
+
+    private boolean validateGetClientRequest(Object obj) {
+        if (obj instanceof GetClientRequest) {
+            GetClientRequest request = (GetClientRequest) obj;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method getClient");
+        }
+        return true;
+    }
+
+    private boolean validateDeleteClientRequest(Object obj) {
+        if (obj instanceof DeleteClientRequest) {
+            DeleteClientRequest request = (DeleteClientRequest) obj;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getPerformedBy() == null || request.getPerformedBy().trim().equals("")) {
+                throw new MissingParameterException("Performed By should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method deleteClient");
+        }
+        return true;
+    }
+
+
+    private boolean validateAddToCache(Object object, String methodName) {
+        if (object instanceof CacheManipulationRequest) {
+            CacheManipulationRequest request = (CacheManipulationRequest) object;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getInstitutionIdsList() == null || request.getInstitutionIdsList().isEmpty()) {
+                throw new MissingParameterException("Institutional id list is empty", null);
+            }
+
+            if (request.getType() == null) {
+                throw new MissingParameterException("Type should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method addToCache");
+        }
+        return true;
+
+
+    }
+
+
+    private boolean validateRemoveToCache(Object object, String methodName) {
+        if (object instanceof CacheManipulationRequest) {
+            CacheManipulationRequest request = (CacheManipulationRequest) object;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getInstitutionIdsList() == null || request.getInstitutionIdsList().isEmpty()) {
+                throw new MissingParameterException("Institutional id list is empty", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+
+    }
+
+
+    private boolean validateGetFromCache(Object object, String methodName) {
+        if (object instanceof CacheManipulationRequest) {
+            CacheManipulationRequest request = (CacheManipulationRequest) object;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getType() == null) {
+                throw new MissingParameterException("Type cannot be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+
+    }
+
+
+}
diff --git a/custos-core-services/federated-authentication-core-service/src/main/proto/FederatedAuthenticationService.proto b/custos-core-services/federated-authentication-core-service/src/main/proto/FederatedAuthenticationService.proto
new file mode 100644
index 0000000..ed554f0
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/proto/FederatedAuthenticationService.proto
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.federated.authentication.service;
+import "google/protobuf/struct.proto";
+
+enum InstitutionCacheType {
+    WHITELIST = 0;
+    BACKLIST = 1;
+}
+
+
+message ClientMetadata {
+    int64 tenantId = 1;
+    string tenantName = 2;
+    repeated string scope = 3;
+    string tenantURI = 4;
+    repeated string contacts = 5;
+    string comment = 6;
+    repeated string redirectURIs = 7;
+    string clientId = 8;
+    string performedBy = 9;
+}
+
+
+message RegisterClientResponse {
+    string clientId = 1;
+    string clientSecret = 2;
+    int64 clientIdIssuedAt = 3;
+    int64 clientSecretExpiresAt = 4;
+    string clientRegistrationUri = 5;
+}
+
+
+message GetClientRequest {
+    int64 tenantId = 1;
+    string clientId = 2;
+}
+
+message GetClientResponse {
+    string clientId = 1;
+    string clientName = 2;
+    repeated string redirectURIs = 3;
+    repeated string grantTypes = 4;
+    repeated string scope = 5;
+    int64 clientIdIssuedAt = 6;
+    string comment = 7;
+    string clientSecret = 8;
+    int64 clientSecretExpiresAt = 9;
+    string clientRegistrationUri = 10;
+}
+
+message DeleteClientRequest {
+    int64 tenantId = 1;
+    string clientId = 2;
+    string performedBy = 3;
+}
+
+message Empty {
+
+}
+
+message GetOperationsMetadataRequest {
+    int64 traceId = 1;
+}
+
+message OperationMetadata {
+    string event = 1;
+    string status = 2;
+    string timeStamp = 3;
+    string performedBy = 4;
+}
+message GetOperationsMetadataResponse {
+    repeated OperationMetadata metadata = 1;
+}
+
+
+message CacheManipulationRequest {
+    int64 tenant_id = 1;
+    repeated string institution_ids = 2;
+    InstitutionCacheType type = 3;
+    string performedBy = 4;
+}
+
+message Status {
+    bool status = 1;
+}
+
+message InstitutionOperationResponse {
+
+}
+
+message Institution {
+    string entity_id = 1;
+    string organization_name = 2;
+    string display_name = 3;
+    bool rand_s = 4;
+}
+
+message GetInstitutionsIdsAsResponse {
+   repeated string entity_ids = 1;
+}
+
+
+message GetInstitutionsResponse {
+    repeated Institution institutions = 2;
+}
+
+
+service FederatedAuthenticationService {
+    rpc addClient (ClientMetadata) returns (RegisterClientResponse);
+    rpc updateClient (ClientMetadata) returns (Empty);
+    rpc getClient (GetClientRequest) returns (GetClientResponse);
+    rpc deleteClient (DeleteClientRequest) returns (Empty);
+    rpc getOperationMetadata (GetOperationsMetadataRequest) returns (GetOperationsMetadataResponse);
+
+    rpc addToCache (CacheManipulationRequest) returns (Status);
+    rpc removeFromCache (CacheManipulationRequest) returns (Status);
+    rpc getFromCache (CacheManipulationRequest) returns (GetInstitutionsResponse);
+    rpc getInstitutions (CacheManipulationRequest) returns (GetInstitutionsResponse);
+
+}
\ No newline at end of file
diff --git a/custos-core-services/federated-authentication-core-service/src/main/resources/application.properties b/custos-core-services/federated-authentication-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..1904647
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/resources/application.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=federatedAuthenticationCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_federated_authentication?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
diff --git a/custos-core-services/federated-authentication-core-service/src/main/resources/bootstrap.properties b/custos-core-services/federated-authentication-core-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..760bf92
--- /dev/null
+++ b/custos-core-services/federated-authentication-core-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+spring.profiles.active:default
\ No newline at end of file
diff --git a/custos-core-services/iam-admin-core-service/Dockerfile b/custos-core-services/iam-admin-core-service/Dockerfile
new file mode 100644
index 0000000..7271b96
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/Dockerfile
@@ -0,0 +1,6 @@
+FROM openjdk:11-jre-slim
+COPY src/main/resources/keycloak-client-truststore.pkcs12 /home/ubuntu/keystore/keycloak-client-truststore.pkcs12
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/iam-admin-core-service/IamAdminService_pb2.py b/custos-core-services/iam-admin-core-service/IamAdminService_pb2.py
new file mode 100644
index 0000000..a7e7c0e
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/IamAdminService_pb2.py
@@ -0,0 +1,3592 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: IamAdminService.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='IamAdminService.proto',
+  package='org.apache.custos.iam.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x15IamAdminService.proto\x12\x1dorg.apache.custos.iam.service\x1a\x1bgoogle/protobuf/empty.proto\"\x84\x02\n\x12SetUpTenantRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x12\n\ntenantName\x18\x02 \x01(\t\x12\x15\n\radminUsername\x18\x03 \x01(\t\x12\x16\n\x0e\x61\x64minFirstname\x18\x04 \x01(\t\x12\x15\n\radminLastname\x18\x05 \x01(\t\x12\x12\n\nadminEmail\x18\x06 \x01(\t\x12\x15\n\radminPassword\x18\x07 \x01(\t\x12\x11\n\ttenantURL\x18\x08 \x01(\t\x12\x16\n\x0erequesterEmail\x18\t \x01(\t\x12\x14\n\x0credirectURIs\x18\n \x03(\t\x12\x16\n\x0e\x63ustosClientId\x18\x0b \x01(\t\"\xd6\x02\n\x1b\x43onfigureFederateIDPRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12:\n\x04type\x18\x02 \x01(\x0e\x32,.org.apache.custos.iam.service.FederatedIDPs\x12\x10\n\x08\x63lientID\x18\x03 \x01(\t\x12\x11\n\tclientSec\x18\x04 \x01(\t\x12\\\n\tconfigMap\x18\x05 \x03(\x0b\x32I.org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry\x12\x16\n\x0erequesterEmail\x18\x06 \x01(\t\x12\r\n\x05idpId\x18\x07 \x01(\t\x12\r\n\x05scope\x18\x08 \x01(\t\x1a\x30\n\x0e\x43onfigMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"%\n\x13\x46\x65\x64\x65rateIDPResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08\"=\n\x13SetUpTenantResponse\x12\x10\n\x08\x63lientId\x18\x01 \x01(\t\x12\x14\n\x0c\x63lientSecret\x18\x02 \x01(\t\"U\n\x1aIsUsernameAvailableRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x10\n\x08userName\x18\x03 \x01(\t\"$\n\x10\x43heckingResponse\x12\x10\n\x08is_exist\x18\x01 \x01(\x08\"\xc0\x02\n\x12UserRepresentation\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x12\n\nfirst_name\x18\x04 \x01(\t\x12\x11\n\tlast_name\x18\x05 \x01(\t\x12\x10\n\x08password\x18\x06 \x01(\t\x12\r\n\x05\x65mail\x18\x07 \x01(\t\x12\x1a\n\x12temporary_password\x18\x08 \x01(\x08\x12\x13\n\x0brealm_roles\x18\t \x03(\t\x12\x14\n\x0c\x63lient_roles\x18\n \x03(\t\x12@\n\nattributes\x18\x0b \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12\r\n\x05state\x18\x0c \x01(\t\x12\x15\n\rcreation_time\x18\r \x01(\x01\x12\x15\n\rlast_login_at\x18\x0e \x01(\x01\"\xcc\x02\n\x13GroupRepresentation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\x13\n\x0brealm_roles\x18\x03 \x03(\t\x12\x14\n\x0c\x63lient_roles\x18\x04 \x03(\t\x12@\n\nattributes\x18\x05 \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12@\n\x05users\x18\x06 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\x12\x46\n\nsub_groups\x18\x07 \x03(\x0b\x32\x32.org.apache.custos.iam.service.GroupRepresentation\x12\x13\n\x0b\x64\x65scription\x18\x08 \x01(\t\x12\x0f\n\x07ownerId\x18\t \x01(\t\"\xb7\x01\n\x13RegisterUserRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x10\n\x08\x63lientId\x18\x03 \x01(\t\x12\x11\n\tclientSec\x18\x04 \x01(\t\x12?\n\x04user\x18\x05 \x01(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\"\xa6\x01\n\x14RegisterUsersRequest\x12@\n\x05users\x18\x01 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\x12\x10\n\x08tenantId\x18\x02 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\x13\n\x0bperformedBy\x18\x05 \x01(\t\"-\n\x14RegisterUserResponse\x12\x15\n\ris_registered\x18\x01 \x01(\x08\"|\n\x15RegisterUsersResponse\x12\x1b\n\x13\x61llUseresRegistered\x18\x01 \x01(\x08\x12\x46\n\x0b\x66\x61iledUsers\x18\x02 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\"h\n\x12UserSearchMetadata\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x12\n\nfirst_name\x18\x02 \x01(\t\x12\x11\n\tlast_name\x18\x03 \x01(\t\x12\r\n\x05\x65mail\x18\x04 \x01(\t\x12\n\n\x02id\x18\x05 \x01(\t\"\xc0\x01\n\x10\x46indUsersRequest\x12?\n\x04user\x18\x03 \x01(\x0b\x32\x31.org.apache.custos.iam.service.UserSearchMetadata\x12\x0e\n\x06offset\x18\x04 \x01(\x05\x12\r\n\x05limit\x18\x05 \x01(\x05\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x11\n\tclient_id\x18\x06 \x01(\t\x12\x12\n\nclient_sec\x18\x07 \x01(\t\"\xb7\x01\n\x11UserSearchRequest\x12?\n\x04user\x18\x01 \x01(\x0b\x32\x31.org.apache.custos.iam.service.UserSearchMetadata\x12\x10\n\x08tenantId\x18\x02 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x03 \x01(\t\x12\x11\n\tclient_id\x18\x04 \x01(\t\x12\x12\n\nclient_sec\x18\x05 \x01(\t\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\"U\n\x11\x46indUsersResponse\x12@\n\x05users\x18\x01 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\"\x83\x01\n\x11ResetUserPassword\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x10\n\x08password\x18\x02 \x01(\t\x12\x10\n\x08tenantId\x18\x03 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x04 \x01(\t\x12\x10\n\x08\x63lientId\x18\x05 \x01(\t\x12\x11\n\tclientSec\x18\x06 \x01(\t\"\xad\x01\n\x16\x44\x65leteUserRolesRequest\x12\x11\n\ttenant_id\x18\x01 \x01(\x03\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x14\n\x0c\x63lient_roles\x18\x03 \x03(\t\x12\r\n\x05roles\x18\x04 \x03(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x05 \x01(\t\x12\x11\n\tclient_id\x18\x06 \x01(\t\x12\x14\n\x0cperformed_by\x18\x07 \x01(\t\x12\n\n\x02id\x18\x08 \x01(\t\"\xaf\x01\n\x13\x41\x64\x64UserRolesRequest\x12\x11\n\ttenant_id\x18\x01 \x01(\x03\x12\x11\n\tusernames\x18\x02 \x03(\t\x12\r\n\x05roles\x18\x03 \x03(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x04 \x01(\t\x12\x11\n\tclient_id\x18\x05 \x01(\t\x12\x14\n\x0c\x63lient_level\x18\x06 \x01(\x08\x12\x14\n\x0cperformed_by\x18\x07 \x01(\t\x12\x0e\n\x06\x61gents\x18\x08 \x03(\t\"\x82\x01\n\x18UpdateUserProfileRequest\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x01 \x01(\t\x12\x10\n\x08tenantId\x18\x02 \x01(\x03\x12?\n\x04user\x18\x03 \x01(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation\"\x1f\n\x0f\x41\x64\x64UserResponse\x12\x0c\n\x04\x63ode\x18\x01 \x01(\t\"/\n\x1cGetOperationsMetadataRequest\x12\x0f\n\x07traceId\x18\x01 \x01(\x03\"Z\n\x11OperationMetadata\x12\r\n\x05\x65vent\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\x12\x11\n\ttimeStamp\x18\x03 \x01(\t\x12\x13\n\x0bperformedBy\x18\x04 \x01(\t\"c\n\x1dGetOperationsMetadataResponse\x12\x42\n\x08metadata\x18\x01 \x03(\x0b\x32\x30.org.apache.custos.iam.service.OperationMetadata\"\'\n\x13\x44\x65leteTenantRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\"\x8f\x01\n\x0f\x41\x64\x64RolesRequest\x12@\n\x05roles\x18\x01 \x03(\x0b\x32\x31.org.apache.custos.iam.service.RoleRepresentation\x12\x14\n\x0c\x63lient_level\x18\x02 \x01(\x08\x12\x11\n\ttenant_id\x18\x03 \x01(\x03\x12\x11\n\tclient_id\x18\x04 \x01(\t\"M\n\x0fGetRolesRequest\x12\x14\n\x0c\x63lient_level\x18\x01 \x01(\x08\x12\x11\n\ttenant_id\x18\x02 \x01(\x03\x12\x11\n\tclient_id\x18\x03 \x01(\t\"J\n\x12RoleRepresentation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x11\n\tcomposite\x18\x03 \x01(\x08\"[\n\x08\x41llRoles\x12@\n\x05roles\x18\x01 \x03(\x0b\x32\x31.org.apache.custos.iam.service.RoleRepresentation\x12\r\n\x05scope\x18\x02 \x01(\t\"\x88\x03\n\x18\x41\x64\x64ProtocolMapperRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x16\n\x0e\x61ttribute_name\x18\x02 \x01(\t\x12\x12\n\nclaim_name\x18\x03 \x01(\t\x12\x41\n\nclaim_type\x18\x04 \x01(\x0e\x32-.org.apache.custos.iam.service.ClaimJSONTypes\x12\x11\n\ttenant_id\x18\x06 \x01(\x03\x12\x11\n\tclient_id\x18\x07 \x01(\t\x12?\n\x0bmapper_type\x18\x08 \x01(\x0e\x32*.org.apache.custos.iam.service.MapperTypes\x12\x17\n\x0f\x61\x64\x64_to_id_token\x18\t \x01(\x08\x12\x1b\n\x13\x61\x64\x64_to_access_token\x18\n \x01(\x08\x12\x18\n\x10\x61\x64\x64_to_user_info\x18\x0b \x01(\x08\x12\x14\n\x0cmulti_valued\x18\x0c \x01(\x08\x12\"\n\x1a\x61ggregate_attribute_values\x18\r \x01(\x08\"!\n\x0fOperationStatus\x12\x0e\n\x06status\x18\x01 \x01(\x08\"\xcc\x01\n\x18\x41\x64\x64UserAttributesRequest\x12@\n\nattributes\x18\x01 \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12\r\n\x05users\x18\x02 \x03(\t\x12\x11\n\ttenant_id\x18\x03 \x01(\x03\x12\x11\n\tclient_id\x18\x04 \x01(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x05 \x01(\t\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\x12\x0e\n\x06\x61gents\x18\x07 \x03(\t\"\xce\x01\n\x1a\x44\x65leteUserAttributeRequest\x12@\n\nattributes\x18\x01 \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12\r\n\x05users\x18\x02 \x03(\t\x12\x11\n\ttenant_id\x18\x03 \x01(\x03\x12\x11\n\tclient_id\x18\x04 \x01(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x05 \x01(\t\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\x12\x0e\n\x06\x61gents\x18\x07 \x03(\t\",\n\rUserAttribute\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x0e\n\x06values\x18\x02 \x03(\t\"\x8e\x01\n\x17\x45ventPersistenceRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x64min_event\x18\x02 \x01(\x08\x12\r\n\x05\x65vent\x18\x03 \x01(\t\x12\x0e\n\x06\x65nable\x18\x04 \x01(\x08\x12\x18\n\x10persistence_time\x18\x05 \x01(\x03\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\"\xb4\x01\n\rGroupsRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x13\n\x0bperformedBy\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\x11\n\tclientSec\x18\x05 \x01(\t\x12\x42\n\x06groups\x18\x06 \x03(\x0b\x32\x32.org.apache.custos.iam.service.GroupRepresentation\"\xbe\x01\n\x0cGroupRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x13\n\x0bperformedBy\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\x11\n\tclientSec\x18\x05 \x01(\t\x12\n\n\x02id\x18\x06 \x01(\t\x12\x41\n\x05group\x18\x07 \x01(\x0b\x32\x32.org.apache.custos.iam.service.GroupRepresentation\"T\n\x0eGroupsResponse\x12\x42\n\x06groups\x18\x01 \x03(\x0b\x32\x32.org.apache.custos.iam.service.GroupRepresentation\"\xb7\x01\n\x17UserGroupMappingRequest\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63\x63\x65ssToken\x18\x02 \x01(\t\x12\x13\n\x0bperformedBy\x18\x03 \x01(\t\x12\x10\n\x08\x63lientId\x18\x04 \x01(\t\x12\x11\n\tclientSec\x18\x05 \x01(\t\x12\x10\n\x08username\x18\x06 \x01(\t\x12\x10\n\x08group_id\x18\x07 \x01(\t\x12\x17\n\x0fmembership_type\x18\x08 \x01(\t\"\xaf\x01\n\x13\x41gentClientMetadata\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x11\n\ttenantURL\x18\x02 \x01(\t\x12\x14\n\x0credirectURIs\x18\x03 \x03(\t\x12\x12\n\nclientName\x18\x04 \x01(\t\x12\x1e\n\x16\x61\x63\x63\x65ss_token_life_time\x18\x05 \x01(\x03\x12\x13\n\x0bperformedBy\x18\x06 \x01(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x07 \x01(\t\"\xc4\x01\n\x05\x41gent\x12\n\n\x02id\x18\x01 \x01(\t\x12\x13\n\x0brealm_roles\x18\x02 \x03(\t\x12@\n\nattributes\x18\x03 \x03(\x0b\x32,.org.apache.custos.iam.service.UserAttribute\x12\x11\n\tisEnabled\x18\x04 \x01(\x08\x12\x15\n\rcreation_time\x18\x05 \x01(\x01\x12\x18\n\x10last_modified_at\x18\x06 \x01(\x01\x12\x14\n\x0c\x63lient_roles\x18\x07 \x03(\t\"z\n\x0fGetAllResources\x12\x10\n\x08tenantId\x18\x01 \x01(\x03\x12\x10\n\x08\x63lientId\x18\x02 \x01(\t\x12\x43\n\rresource_type\x18\x03 \x01(\x0e\x32,.org.apache.custos.iam.service.ResourceTypes\"\x91\x01\n\x17GetAllResourcesResponse\x12\x34\n\x06\x61gents\x18\x01 \x03(\x0b\x32$.org.apache.custos.iam.service.Agent\x12@\n\x05users\x18\x02 \x03(\x0b\x32\x31.org.apache.custos.iam.service.UserRepresentation*b\n\rFederatedIDPs\x12\x0b\n\x07\x43ILOGON\x10\x00\x12\x0c\n\x08\x46\x41\x43\x45\x42OOK\x10\x01\x12\n\n\x06GOOGLE\x10\x02\x12\x0c\n\x08LINKEDIN\x10\x03\x12\x0b\n\x07TWITTER\x10\x04\x12\x0f\n\x0b\x43USTOM_OIDC\x10\x05*L\n\x0bMapperTypes\x12\x12\n\x0eUSER_ATTRIBUTE\x10\x00\x12\x13\n\x0fUSER_REALM_ROLE\x10\x01\x12\x14\n\x10USER_CLIENT_ROLE\x10\x02*J\n\x0e\x43laimJSONTypes\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04LONG\x10\x01\x12\x0b\n\x07INTEGER\x10\x02\x12\x0b\n\x07\x42OOLEAN\x10\x03\x12\x08\n\x04JSON\x10\x04*$\n\rResourceTypes\x12\x08\n\x04USER\x10\x00\x12\t\n\x05\x41GENT\x10\x01\x32\x81,\n\x0fIamAdminService\x12t\n\x0bsetUPTenant\x12\x31.org.apache.custos.iam.service.SetUpTenantRequest\x1a\x32.org.apache.custos.iam.service.SetUpTenantResponse\x12u\n\x0cupdateTenant\x12\x31.org.apache.custos.iam.service.SetUpTenantRequest\x1a\x32.org.apache.custos.iam.service.SetUpTenantResponse\x12Z\n\x0c\x64\x65leteTenant\x12\x32.org.apache.custos.iam.service.DeleteTenantRequest\x1a\x16.google.protobuf.Empty\x12\x87\x01\n\x15\x63onfigureFederatedIDP\x12:.org.apache.custos.iam.service.ConfigureFederateIDPRequest\x1a\x32.org.apache.custos.iam.service.FederateIDPResponse\x12k\n\x10\x61\x64\x64RolesToTenant\x12..org.apache.custos.iam.service.AddRolesRequest\x1a\'.org.apache.custos.iam.service.AllRoles\x12|\n\x11\x61\x64\x64ProtocolMapper\x12\x37.org.apache.custos.iam.service.AddProtocolMapperRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12k\n\x10getRolesOfTenant\x12..org.apache.custos.iam.service.GetRolesRequest\x1a\'.org.apache.custos.iam.service.AllRoles\x12w\n\x13isUsernameAvailable\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12w\n\x0cregisterUser\x12\x32.org.apache.custos.iam.service.RegisterUserRequest\x1a\x33.org.apache.custos.iam.service.RegisterUserResponse\x12q\n\nenableUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a\x31.org.apache.custos.iam.service.UserRepresentation\x12r\n\x0b\x64isableUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a\x31.org.apache.custos.iam.service.UserRepresentation\x12q\n\risUserEnabled\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12p\n\x0bisUserExist\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a/.org.apache.custos.iam.service.CheckingResponse\x12n\n\x07getUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a\x31.org.apache.custos.iam.service.UserRepresentation\x12n\n\tfindUsers\x12/.org.apache.custos.iam.service.FindUsersRequest\x1a\x30.org.apache.custos.iam.service.FindUsersResponse\x12q\n\rresetPassword\x12\x30.org.apache.custos.iam.service.ResetUserPassword\x1a..org.apache.custos.iam.service.OperationStatus\x12w\n\x13grantAdminPrivilege\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12x\n\x14removeAdminPrivilege\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x83\x01\n\x16registerAndEnableUsers\x12\x33.org.apache.custos.iam.service.RegisterUsersRequest\x1a\x34.org.apache.custos.iam.service.RegisterUsersResponse\x12|\n\x11\x61\x64\x64UserAttributes\x12\x37.org.apache.custos.iam.service.AddUserAttributesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x81\x01\n\x14\x64\x65leteUserAttributes\x12\x39.org.apache.custos.iam.service.DeleteUserAttributeRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12u\n\x0f\x61\x64\x64RolesToUsers\x12\x32.org.apache.custos.iam.service.AddUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12n\n\ndeleteUser\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12|\n\x13\x64\x65leteRolesFromUser\x12\x35.org.apache.custos.iam.service.DeleteUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12|\n\x11updateUserProfile\x12\x37.org.apache.custos.iam.service.UpdateUserProfileRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x91\x01\n\x14getOperationMetadata\x12;.org.apache.custos.iam.service.GetOperationsMetadataRequest\x1a<.org.apache.custos.iam.service.GetOperationsMetadataResponse\x12\x83\x01\n\x19\x63onfigureEventPersistence\x12\x36.org.apache.custos.iam.service.EventPersistenceRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12k\n\x0c\x63reateGroups\x12,.org.apache.custos.iam.service.GroupsRequest\x1a-.org.apache.custos.iam.service.GroupsResponse\x12n\n\x0bupdateGroup\x12+.org.apache.custos.iam.service.GroupRequest\x1a\x32.org.apache.custos.iam.service.GroupRepresentation\x12j\n\x0b\x64\x65leteGroup\x12+.org.apache.custos.iam.service.GroupRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12l\n\tfindGroup\x12+.org.apache.custos.iam.service.GroupRequest\x1a\x32.org.apache.custos.iam.service.GroupRepresentation\x12j\n\x0cgetAllGroups\x12+.org.apache.custos.iam.service.GroupRequest\x1a-.org.apache.custos.iam.service.GroupsResponse\x12x\n\x0e\x61\x64\x64UserToGroup\x12\x36.org.apache.custos.iam.service.UserGroupMappingRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12}\n\x13removeUserFromGroup\x12\x36.org.apache.custos.iam.service.UserGroupMappingRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12{\n\x11\x63reateAgentClient\x12\x32.org.apache.custos.iam.service.AgentClientMetadata\x1a\x32.org.apache.custos.iam.service.SetUpTenantResponse\x12z\n\x14\x63onfigureAgentClient\x12\x32.org.apache.custos.iam.service.AgentClientMetadata\x1a..org.apache.custos.iam.service.OperationStatus\x12x\n\x14isAgentNameAvailable\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x81\x01\n\x16registerAndEnableAgent\x12\x32.org.apache.custos.iam.service.RegisterUserRequest\x1a\x33.org.apache.custos.iam.service.RegisterUserResponse\x12o\n\x0b\x64\x65leteAgent\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x62\n\x08getAgent\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a$.org.apache.custos.iam.service.Agent\x12p\n\x0c\x64isableAgent\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12o\n\x0b\x65nableAgent\x12\x30.org.apache.custos.iam.service.UserSearchRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12}\n\x12\x61\x64\x64\x41gentAttributes\x12\x37.org.apache.custos.iam.service.AddUserAttributesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12\x82\x01\n\x15\x64\x65leteAgentAttributes\x12\x39.org.apache.custos.iam.service.DeleteUserAttributeRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12u\n\x0f\x61\x64\x64RolesToAgent\x12\x32.org.apache.custos.iam.service.AddUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12y\n\x10\x64\x65leteAgentRoles\x12\x35.org.apache.custos.iam.service.DeleteUserRolesRequest\x1a..org.apache.custos.iam.service.OperationStatus\x12y\n\x0fgetAllResources\x12..org.apache.custos.iam.service.GetAllResources\x1a\x36.org.apache.custos.iam.service.GetAllResourcesResponseB\x02P\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
+
+_FEDERATEDIDPS = _descriptor.EnumDescriptor(
+  name='FederatedIDPs',
+  full_name='org.apache.custos.iam.service.FederatedIDPs',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='CILOGON', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='FACEBOOK', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='GOOGLE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='LINKEDIN', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='TWITTER', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CUSTOM_OIDC', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=6345,
+  serialized_end=6443,
+)
+_sym_db.RegisterEnumDescriptor(_FEDERATEDIDPS)
+
+FederatedIDPs = enum_type_wrapper.EnumTypeWrapper(_FEDERATEDIDPS)
+_MAPPERTYPES = _descriptor.EnumDescriptor(
+  name='MapperTypes',
+  full_name='org.apache.custos.iam.service.MapperTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='USER_ATTRIBUTE', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='USER_REALM_ROLE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='USER_CLIENT_ROLE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=6445,
+  serialized_end=6521,
+)
+_sym_db.RegisterEnumDescriptor(_MAPPERTYPES)
+
+MapperTypes = enum_type_wrapper.EnumTypeWrapper(_MAPPERTYPES)
+_CLAIMJSONTYPES = _descriptor.EnumDescriptor(
+  name='ClaimJSONTypes',
+  full_name='org.apache.custos.iam.service.ClaimJSONTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='STRING', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='LONG', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='INTEGER', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='BOOLEAN', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='JSON', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=6523,
+  serialized_end=6597,
+)
+_sym_db.RegisterEnumDescriptor(_CLAIMJSONTYPES)
+
+ClaimJSONTypes = enum_type_wrapper.EnumTypeWrapper(_CLAIMJSONTYPES)
+_RESOURCETYPES = _descriptor.EnumDescriptor(
+  name='ResourceTypes',
+  full_name='org.apache.custos.iam.service.ResourceTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='USER', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='AGENT', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=6599,
+  serialized_end=6635,
+)
+_sym_db.RegisterEnumDescriptor(_RESOURCETYPES)
+
+ResourceTypes = enum_type_wrapper.EnumTypeWrapper(_RESOURCETYPES)
+CILOGON = 0
+FACEBOOK = 1
+GOOGLE = 2
+LINKEDIN = 3
+TWITTER = 4
+CUSTOM_OIDC = 5
+USER_ATTRIBUTE = 0
+USER_REALM_ROLE = 1
+USER_CLIENT_ROLE = 2
+STRING = 0
+LONG = 1
+INTEGER = 2
+BOOLEAN = 3
+JSON = 4
+USER = 0
+AGENT = 1
+
+
+
+_SETUPTENANTREQUEST = _descriptor.Descriptor(
+  name='SetUpTenantRequest',
+  full_name='org.apache.custos.iam.service.SetUpTenantRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.SetUpTenantRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantName', full_name='org.apache.custos.iam.service.SetUpTenantRequest.tenantName', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminUsername', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminUsername', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminFirstname', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminFirstname', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminLastname', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminLastname', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminEmail', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminEmail', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='adminPassword', full_name='org.apache.custos.iam.service.SetUpTenantRequest.adminPassword', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantURL', full_name='org.apache.custos.iam.service.SetUpTenantRequest.tenantURL', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='requesterEmail', full_name='org.apache.custos.iam.service.SetUpTenantRequest.requesterEmail', index=8,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='redirectURIs', full_name='org.apache.custos.iam.service.SetUpTenantRequest.redirectURIs', index=9,
+      number=10, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='custosClientId', full_name='org.apache.custos.iam.service.SetUpTenantRequest.custosClientId', index=10,
+      number=11, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=86,
+  serialized_end=346,
+)
+
+
+_CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY = _descriptor.Descriptor(
+  name='ConfigMapEntry',
+  full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=b'8\001',
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=643,
+  serialized_end=691,
+)
+
+_CONFIGUREFEDERATEIDPREQUEST = _descriptor.Descriptor(
+  name='ConfigureFederateIDPRequest',
+  full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientID', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.clientID', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.clientSec', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='configMap', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.configMap', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='requesterEmail', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.requesterEmail', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='idpId', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.idpId', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.iam.service.ConfigureFederateIDPRequest.scope', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[_CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY, ],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=349,
+  serialized_end=691,
+)
+
+
+_FEDERATEIDPRESPONSE = _descriptor.Descriptor(
+  name='FederateIDPResponse',
+  full_name='org.apache.custos.iam.service.FederateIDPResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.iam.service.FederateIDPResponse.status', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=693,
+  serialized_end=730,
+)
+
+
+_SETUPTENANTRESPONSE = _descriptor.Descriptor(
+  name='SetUpTenantResponse',
+  full_name='org.apache.custos.iam.service.SetUpTenantResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.SetUpTenantResponse.clientId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSecret', full_name='org.apache.custos.iam.service.SetUpTenantResponse.clientSecret', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=732,
+  serialized_end=793,
+)
+
+
+_ISUSERNAMEAVAILABLEREQUEST = _descriptor.Descriptor(
+  name='IsUsernameAvailableRequest',
+  full_name='org.apache.custos.iam.service.IsUsernameAvailableRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.IsUsernameAvailableRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.IsUsernameAvailableRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='userName', full_name='org.apache.custos.iam.service.IsUsernameAvailableRequest.userName', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=795,
+  serialized_end=880,
+)
+
+
+_CHECKINGRESPONSE = _descriptor.Descriptor(
+  name='CheckingResponse',
+  full_name='org.apache.custos.iam.service.CheckingResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='is_exist', full_name='org.apache.custos.iam.service.CheckingResponse.is_exist', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=882,
+  serialized_end=918,
+)
+
+
+_USERREPRESENTATION = _descriptor.Descriptor(
+  name='UserRepresentation',
+  full_name='org.apache.custos.iam.service.UserRepresentation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.UserRepresentation.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.UserRepresentation.username', index=1,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='first_name', full_name='org.apache.custos.iam.service.UserRepresentation.first_name', index=2,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_name', full_name='org.apache.custos.iam.service.UserRepresentation.last_name', index=3,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='password', full_name='org.apache.custos.iam.service.UserRepresentation.password', index=4,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='email', full_name='org.apache.custos.iam.service.UserRepresentation.email', index=5,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='temporary_password', full_name='org.apache.custos.iam.service.UserRepresentation.temporary_password', index=6,
+      number=8, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='realm_roles', full_name='org.apache.custos.iam.service.UserRepresentation.realm_roles', index=7,
+      number=9, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.iam.service.UserRepresentation.client_roles', index=8,
+      number=10, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.UserRepresentation.attributes', index=9,
+      number=11, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='state', full_name='org.apache.custos.iam.service.UserRepresentation.state', index=10,
+      number=12, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='creation_time', full_name='org.apache.custos.iam.service.UserRepresentation.creation_time', index=11,
+      number=13, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_login_at', full_name='org.apache.custos.iam.service.UserRepresentation.last_login_at', index=12,
+      number=14, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=921,
+  serialized_end=1241,
+)
+
+
+_GROUPREPRESENTATION = _descriptor.Descriptor(
+  name='GroupRepresentation',
+  full_name='org.apache.custos.iam.service.GroupRepresentation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.iam.service.GroupRepresentation.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.GroupRepresentation.id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='realm_roles', full_name='org.apache.custos.iam.service.GroupRepresentation.realm_roles', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.iam.service.GroupRepresentation.client_roles', index=3,
+      number=4, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.GroupRepresentation.attributes', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.GroupRepresentation.users', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='sub_groups', full_name='org.apache.custos.iam.service.GroupRepresentation.sub_groups', index=6,
+      number=7, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='org.apache.custos.iam.service.GroupRepresentation.description', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='ownerId', full_name='org.apache.custos.iam.service.GroupRepresentation.ownerId', index=8,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1244,
+  serialized_end=1576,
+)
+
+
+_REGISTERUSERREQUEST = _descriptor.Descriptor(
+  name='RegisterUserRequest',
+  full_name='org.apache.custos.iam.service.RegisterUserRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.RegisterUserRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.RegisterUserRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.RegisterUserRequest.clientId', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.RegisterUserRequest.clientSec', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='user', full_name='org.apache.custos.iam.service.RegisterUserRequest.user', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.RegisterUserRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1579,
+  serialized_end=1762,
+)
+
+
+_REGISTERUSERSREQUEST = _descriptor.Descriptor(
+  name='RegisterUsersRequest',
+  full_name='org.apache.custos.iam.service.RegisterUsersRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.RegisterUsersRequest.users', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.RegisterUsersRequest.tenantId', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.RegisterUsersRequest.accessToken', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.RegisterUsersRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.RegisterUsersRequest.performedBy', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1765,
+  serialized_end=1931,
+)
+
+
+_REGISTERUSERRESPONSE = _descriptor.Descriptor(
+  name='RegisterUserResponse',
+  full_name='org.apache.custos.iam.service.RegisterUserResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='is_registered', full_name='org.apache.custos.iam.service.RegisterUserResponse.is_registered', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1933,
+  serialized_end=1978,
+)
+
+
+_REGISTERUSERSRESPONSE = _descriptor.Descriptor(
+  name='RegisterUsersResponse',
+  full_name='org.apache.custos.iam.service.RegisterUsersResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='allUseresRegistered', full_name='org.apache.custos.iam.service.RegisterUsersResponse.allUseresRegistered', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='failedUsers', full_name='org.apache.custos.iam.service.RegisterUsersResponse.failedUsers', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1980,
+  serialized_end=2104,
+)
+
+
+_USERSEARCHMETADATA = _descriptor.Descriptor(
+  name='UserSearchMetadata',
+  full_name='org.apache.custos.iam.service.UserSearchMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.UserSearchMetadata.username', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='first_name', full_name='org.apache.custos.iam.service.UserSearchMetadata.first_name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_name', full_name='org.apache.custos.iam.service.UserSearchMetadata.last_name', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='email', full_name='org.apache.custos.iam.service.UserSearchMetadata.email', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.UserSearchMetadata.id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2106,
+  serialized_end=2210,
+)
+
+
+_FINDUSERSREQUEST = _descriptor.Descriptor(
+  name='FindUsersRequest',
+  full_name='org.apache.custos.iam.service.FindUsersRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='user', full_name='org.apache.custos.iam.service.FindUsersRequest.user', index=0,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='offset', full_name='org.apache.custos.iam.service.FindUsersRequest.offset', index=1,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='limit', full_name='org.apache.custos.iam.service.FindUsersRequest.limit', index=2,
+      number=5, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.FindUsersRequest.tenantId', index=3,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.FindUsersRequest.accessToken', index=4,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.FindUsersRequest.client_id', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.iam.service.FindUsersRequest.client_sec', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2213,
+  serialized_end=2405,
+)
+
+
+_USERSEARCHREQUEST = _descriptor.Descriptor(
+  name='UserSearchRequest',
+  full_name='org.apache.custos.iam.service.UserSearchRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='user', full_name='org.apache.custos.iam.service.UserSearchRequest.user', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.UserSearchRequest.tenantId', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.UserSearchRequest.accessToken', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.UserSearchRequest.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_sec', full_name='org.apache.custos.iam.service.UserSearchRequest.client_sec', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.UserSearchRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2408,
+  serialized_end=2591,
+)
+
+
+_FINDUSERSRESPONSE = _descriptor.Descriptor(
+  name='FindUsersResponse',
+  full_name='org.apache.custos.iam.service.FindUsersResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.FindUsersResponse.users', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2593,
+  serialized_end=2678,
+)
+
+
+_RESETUSERPASSWORD = _descriptor.Descriptor(
+  name='ResetUserPassword',
+  full_name='org.apache.custos.iam.service.ResetUserPassword',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.ResetUserPassword.username', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='password', full_name='org.apache.custos.iam.service.ResetUserPassword.password', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.ResetUserPassword.tenantId', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.ResetUserPassword.accessToken', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.ResetUserPassword.clientId', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.ResetUserPassword.clientSec', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2681,
+  serialized_end=2812,
+)
+
+
+_DELETEUSERROLESREQUEST = _descriptor.Descriptor(
+  name='DeleteUserRolesRequest',
+  full_name='org.apache.custos.iam.service.DeleteUserRolesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.tenant_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.username', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.client_roles', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.roles', index=3,
+      number=4, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.access_token', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.client_id', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performed_by', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.performed_by', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.DeleteUserRolesRequest.id', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2815,
+  serialized_end=2988,
+)
+
+
+_ADDUSERROLESREQUEST = _descriptor.Descriptor(
+  name='AddUserRolesRequest',
+  full_name='org.apache.custos.iam.service.AddUserRolesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.AddUserRolesRequest.tenant_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='usernames', full_name='org.apache.custos.iam.service.AddUserRolesRequest.usernames', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='org.apache.custos.iam.service.AddUserRolesRequest.roles', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.AddUserRolesRequest.access_token', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.AddUserRolesRequest.client_id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_level', full_name='org.apache.custos.iam.service.AddUserRolesRequest.client_level', index=5,
+      number=6, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performed_by', full_name='org.apache.custos.iam.service.AddUserRolesRequest.performed_by', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='agents', full_name='org.apache.custos.iam.service.AddUserRolesRequest.agents', index=7,
+      number=8, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2991,
+  serialized_end=3166,
+)
+
+
+_UPDATEUSERPROFILEREQUEST = _descriptor.Descriptor(
+  name='UpdateUserProfileRequest',
+  full_name='org.apache.custos.iam.service.UpdateUserProfileRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.UpdateUserProfileRequest.accessToken', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.UpdateUserProfileRequest.tenantId', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='user', full_name='org.apache.custos.iam.service.UpdateUserProfileRequest.user', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3169,
+  serialized_end=3299,
+)
+
+
+_ADDUSERRESPONSE = _descriptor.Descriptor(
+  name='AddUserResponse',
+  full_name='org.apache.custos.iam.service.AddUserResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='code', full_name='org.apache.custos.iam.service.AddUserResponse.code', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3301,
+  serialized_end=3332,
+)
+
+
+_GETOPERATIONSMETADATAREQUEST = _descriptor.Descriptor(
+  name='GetOperationsMetadataRequest',
+  full_name='org.apache.custos.iam.service.GetOperationsMetadataRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='traceId', full_name='org.apache.custos.iam.service.GetOperationsMetadataRequest.traceId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3334,
+  serialized_end=3381,
+)
+
+
+_OPERATIONMETADATA = _descriptor.Descriptor(
+  name='OperationMetadata',
+  full_name='org.apache.custos.iam.service.OperationMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='org.apache.custos.iam.service.OperationMetadata.event', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.iam.service.OperationMetadata.status', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='timeStamp', full_name='org.apache.custos.iam.service.OperationMetadata.timeStamp', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.OperationMetadata.performedBy', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3383,
+  serialized_end=3473,
+)
+
+
+_GETOPERATIONSMETADATARESPONSE = _descriptor.Descriptor(
+  name='GetOperationsMetadataResponse',
+  full_name='org.apache.custos.iam.service.GetOperationsMetadataResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='metadata', full_name='org.apache.custos.iam.service.GetOperationsMetadataResponse.metadata', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3475,
+  serialized_end=3574,
+)
+
+
+_DELETETENANTREQUEST = _descriptor.Descriptor(
+  name='DeleteTenantRequest',
+  full_name='org.apache.custos.iam.service.DeleteTenantRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.DeleteTenantRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3576,
+  serialized_end=3615,
+)
+
+
+_ADDROLESREQUEST = _descriptor.Descriptor(
+  name='AddRolesRequest',
+  full_name='org.apache.custos.iam.service.AddRolesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='org.apache.custos.iam.service.AddRolesRequest.roles', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_level', full_name='org.apache.custos.iam.service.AddRolesRequest.client_level', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.AddRolesRequest.tenant_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.AddRolesRequest.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3618,
+  serialized_end=3761,
+)
+
+
+_GETROLESREQUEST = _descriptor.Descriptor(
+  name='GetRolesRequest',
+  full_name='org.apache.custos.iam.service.GetRolesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client_level', full_name='org.apache.custos.iam.service.GetRolesRequest.client_level', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.GetRolesRequest.tenant_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.GetRolesRequest.client_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3763,
+  serialized_end=3840,
+)
+
+
+_ROLEREPRESENTATION = _descriptor.Descriptor(
+  name='RoleRepresentation',
+  full_name='org.apache.custos.iam.service.RoleRepresentation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.iam.service.RoleRepresentation.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='org.apache.custos.iam.service.RoleRepresentation.description', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='composite', full_name='org.apache.custos.iam.service.RoleRepresentation.composite', index=2,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3842,
+  serialized_end=3916,
+)
+
+
+_ALLROLES = _descriptor.Descriptor(
+  name='AllRoles',
+  full_name='org.apache.custos.iam.service.AllRoles',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='org.apache.custos.iam.service.AllRoles.roles', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='scope', full_name='org.apache.custos.iam.service.AllRoles.scope', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3918,
+  serialized_end=4009,
+)
+
+
+_ADDPROTOCOLMAPPERREQUEST = _descriptor.Descriptor(
+  name='AddProtocolMapperRequest',
+  full_name='org.apache.custos.iam.service.AddProtocolMapperRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attribute_name', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.attribute_name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='claim_name', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.claim_name', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='claim_type', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.claim_type', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.tenant_id', index=4,
+      number=6, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.client_id', index=5,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='mapper_type', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.mapper_type', index=6,
+      number=8, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='add_to_id_token', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.add_to_id_token', index=7,
+      number=9, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='add_to_access_token', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.add_to_access_token', index=8,
+      number=10, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='add_to_user_info', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.add_to_user_info', index=9,
+      number=11, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='multi_valued', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.multi_valued', index=10,
+      number=12, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='aggregate_attribute_values', full_name='org.apache.custos.iam.service.AddProtocolMapperRequest.aggregate_attribute_values', index=11,
+      number=13, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4012,
+  serialized_end=4404,
+)
+
+
+_OPERATIONSTATUS = _descriptor.Descriptor(
+  name='OperationStatus',
+  full_name='org.apache.custos.iam.service.OperationStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='org.apache.custos.iam.service.OperationStatus.status', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4406,
+  serialized_end=4439,
+)
+
+
+_ADDUSERATTRIBUTESREQUEST = _descriptor.Descriptor(
+  name='AddUserAttributesRequest',
+  full_name='org.apache.custos.iam.service.AddUserAttributesRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.attributes', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.users', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.tenant_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.access_token', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='agents', full_name='org.apache.custos.iam.service.AddUserAttributesRequest.agents', index=6,
+      number=7, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4442,
+  serialized_end=4646,
+)
+
+
+_DELETEUSERATTRIBUTEREQUEST = _descriptor.Descriptor(
+  name='DeleteUserAttributeRequest',
+  full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.attributes', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.users', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenant_id', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.tenant_id', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.access_token', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='agents', full_name='org.apache.custos.iam.service.DeleteUserAttributeRequest.agents', index=6,
+      number=7, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4649,
+  serialized_end=4855,
+)
+
+
+_USERATTRIBUTE = _descriptor.Descriptor(
+  name='UserAttribute',
+  full_name='org.apache.custos.iam.service.UserAttribute',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='org.apache.custos.iam.service.UserAttribute.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='values', full_name='org.apache.custos.iam.service.UserAttribute.values', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4857,
+  serialized_end=4901,
+)
+
+
+_EVENTPERSISTENCEREQUEST = _descriptor.Descriptor(
+  name='EventPersistenceRequest',
+  full_name='org.apache.custos.iam.service.EventPersistenceRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.EventPersistenceRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='admin_event', full_name='org.apache.custos.iam.service.EventPersistenceRequest.admin_event', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='event', full_name='org.apache.custos.iam.service.EventPersistenceRequest.event', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='enable', full_name='org.apache.custos.iam.service.EventPersistenceRequest.enable', index=3,
+      number=4, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='persistence_time', full_name='org.apache.custos.iam.service.EventPersistenceRequest.persistence_time', index=4,
+      number=5, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.EventPersistenceRequest.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4904,
+  serialized_end=5046,
+)
+
+
+_GROUPSREQUEST = _descriptor.Descriptor(
+  name='GroupsRequest',
+  full_name='org.apache.custos.iam.service.GroupsRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.GroupsRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.GroupsRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.GroupsRequest.performedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.GroupsRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.GroupsRequest.clientSec', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='groups', full_name='org.apache.custos.iam.service.GroupsRequest.groups', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5049,
+  serialized_end=5229,
+)
+
+
+_GROUPREQUEST = _descriptor.Descriptor(
+  name='GroupRequest',
+  full_name='org.apache.custos.iam.service.GroupRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.GroupRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.GroupRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.GroupRequest.performedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.GroupRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.GroupRequest.clientSec', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.GroupRequest.id', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='group', full_name='org.apache.custos.iam.service.GroupRequest.group', index=6,
+      number=7, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5232,
+  serialized_end=5422,
+)
+
+
+_GROUPSRESPONSE = _descriptor.Descriptor(
+  name='GroupsResponse',
+  full_name='org.apache.custos.iam.service.GroupsResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='groups', full_name='org.apache.custos.iam.service.GroupsResponse.groups', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5424,
+  serialized_end=5508,
+)
+
+
+_USERGROUPMAPPINGREQUEST = _descriptor.Descriptor(
+  name='UserGroupMappingRequest',
+  full_name='org.apache.custos.iam.service.UserGroupMappingRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='accessToken', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.accessToken', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.performedBy', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.clientId', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientSec', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.clientSec', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='username', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.username', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='group_id', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.group_id', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='membership_type', full_name='org.apache.custos.iam.service.UserGroupMappingRequest.membership_type', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5511,
+  serialized_end=5694,
+)
+
+
+_AGENTCLIENTMETADATA = _descriptor.Descriptor(
+  name='AgentClientMetadata',
+  full_name='org.apache.custos.iam.service.AgentClientMetadata',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.AgentClientMetadata.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tenantURL', full_name='org.apache.custos.iam.service.AgentClientMetadata.tenantURL', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='redirectURIs', full_name='org.apache.custos.iam.service.AgentClientMetadata.redirectURIs', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientName', full_name='org.apache.custos.iam.service.AgentClientMetadata.clientName', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token_life_time', full_name='org.apache.custos.iam.service.AgentClientMetadata.access_token_life_time', index=4,
+      number=5, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='performedBy', full_name='org.apache.custos.iam.service.AgentClientMetadata.performedBy', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access_token', full_name='org.apache.custos.iam.service.AgentClientMetadata.access_token', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5697,
+  serialized_end=5872,
+)
+
+
+_AGENT = _descriptor.Descriptor(
+  name='Agent',
+  full_name='org.apache.custos.iam.service.Agent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='org.apache.custos.iam.service.Agent.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='realm_roles', full_name='org.apache.custos.iam.service.Agent.realm_roles', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='attributes', full_name='org.apache.custos.iam.service.Agent.attributes', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='isEnabled', full_name='org.apache.custos.iam.service.Agent.isEnabled', index=3,
+      number=4, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='creation_time', full_name='org.apache.custos.iam.service.Agent.creation_time', index=4,
+      number=5, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='last_modified_at', full_name='org.apache.custos.iam.service.Agent.last_modified_at', index=5,
+      number=6, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_roles', full_name='org.apache.custos.iam.service.Agent.client_roles', index=6,
+      number=7, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5875,
+  serialized_end=6071,
+)
+
+
+_GETALLRESOURCES = _descriptor.Descriptor(
+  name='GetAllResources',
+  full_name='org.apache.custos.iam.service.GetAllResources',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='tenantId', full_name='org.apache.custos.iam.service.GetAllResources.tenantId', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='clientId', full_name='org.apache.custos.iam.service.GetAllResources.clientId', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_type', full_name='org.apache.custos.iam.service.GetAllResources.resource_type', index=2,
+      number=3, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6073,
+  serialized_end=6195,
+)
+
+
+_GETALLRESOURCESRESPONSE = _descriptor.Descriptor(
+  name='GetAllResourcesResponse',
+  full_name='org.apache.custos.iam.service.GetAllResourcesResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='agents', full_name='org.apache.custos.iam.service.GetAllResourcesResponse.agents', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='users', full_name='org.apache.custos.iam.service.GetAllResourcesResponse.users', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6198,
+  serialized_end=6343,
+)
+
+_CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY.containing_type = _CONFIGUREFEDERATEIDPREQUEST
+_CONFIGUREFEDERATEIDPREQUEST.fields_by_name['type'].enum_type = _FEDERATEDIDPS
+_CONFIGUREFEDERATEIDPREQUEST.fields_by_name['configMap'].message_type = _CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY
+_USERREPRESENTATION.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_GROUPREPRESENTATION.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_GROUPREPRESENTATION.fields_by_name['users'].message_type = _USERREPRESENTATION
+_GROUPREPRESENTATION.fields_by_name['sub_groups'].message_type = _GROUPREPRESENTATION
+_REGISTERUSERREQUEST.fields_by_name['user'].message_type = _USERREPRESENTATION
+_REGISTERUSERSREQUEST.fields_by_name['users'].message_type = _USERREPRESENTATION
+_REGISTERUSERSRESPONSE.fields_by_name['failedUsers'].message_type = _USERREPRESENTATION
+_FINDUSERSREQUEST.fields_by_name['user'].message_type = _USERSEARCHMETADATA
+_USERSEARCHREQUEST.fields_by_name['user'].message_type = _USERSEARCHMETADATA
+_FINDUSERSRESPONSE.fields_by_name['users'].message_type = _USERREPRESENTATION
+_UPDATEUSERPROFILEREQUEST.fields_by_name['user'].message_type = _USERREPRESENTATION
+_GETOPERATIONSMETADATARESPONSE.fields_by_name['metadata'].message_type = _OPERATIONMETADATA
+_ADDROLESREQUEST.fields_by_name['roles'].message_type = _ROLEREPRESENTATION
+_ALLROLES.fields_by_name['roles'].message_type = _ROLEREPRESENTATION
+_ADDPROTOCOLMAPPERREQUEST.fields_by_name['claim_type'].enum_type = _CLAIMJSONTYPES
+_ADDPROTOCOLMAPPERREQUEST.fields_by_name['mapper_type'].enum_type = _MAPPERTYPES
+_ADDUSERATTRIBUTESREQUEST.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_DELETEUSERATTRIBUTEREQUEST.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_GROUPSREQUEST.fields_by_name['groups'].message_type = _GROUPREPRESENTATION
+_GROUPREQUEST.fields_by_name['group'].message_type = _GROUPREPRESENTATION
+_GROUPSRESPONSE.fields_by_name['groups'].message_type = _GROUPREPRESENTATION
+_AGENT.fields_by_name['attributes'].message_type = _USERATTRIBUTE
+_GETALLRESOURCES.fields_by_name['resource_type'].enum_type = _RESOURCETYPES
+_GETALLRESOURCESRESPONSE.fields_by_name['agents'].message_type = _AGENT
+_GETALLRESOURCESRESPONSE.fields_by_name['users'].message_type = _USERREPRESENTATION
+DESCRIPTOR.message_types_by_name['SetUpTenantRequest'] = _SETUPTENANTREQUEST
+DESCRIPTOR.message_types_by_name['ConfigureFederateIDPRequest'] = _CONFIGUREFEDERATEIDPREQUEST
+DESCRIPTOR.message_types_by_name['FederateIDPResponse'] = _FEDERATEIDPRESPONSE
+DESCRIPTOR.message_types_by_name['SetUpTenantResponse'] = _SETUPTENANTRESPONSE
+DESCRIPTOR.message_types_by_name['IsUsernameAvailableRequest'] = _ISUSERNAMEAVAILABLEREQUEST
+DESCRIPTOR.message_types_by_name['CheckingResponse'] = _CHECKINGRESPONSE
+DESCRIPTOR.message_types_by_name['UserRepresentation'] = _USERREPRESENTATION
+DESCRIPTOR.message_types_by_name['GroupRepresentation'] = _GROUPREPRESENTATION
+DESCRIPTOR.message_types_by_name['RegisterUserRequest'] = _REGISTERUSERREQUEST
+DESCRIPTOR.message_types_by_name['RegisterUsersRequest'] = _REGISTERUSERSREQUEST
+DESCRIPTOR.message_types_by_name['RegisterUserResponse'] = _REGISTERUSERRESPONSE
+DESCRIPTOR.message_types_by_name['RegisterUsersResponse'] = _REGISTERUSERSRESPONSE
+DESCRIPTOR.message_types_by_name['UserSearchMetadata'] = _USERSEARCHMETADATA
+DESCRIPTOR.message_types_by_name['FindUsersRequest'] = _FINDUSERSREQUEST
+DESCRIPTOR.message_types_by_name['UserSearchRequest'] = _USERSEARCHREQUEST
+DESCRIPTOR.message_types_by_name['FindUsersResponse'] = _FINDUSERSRESPONSE
+DESCRIPTOR.message_types_by_name['ResetUserPassword'] = _RESETUSERPASSWORD
+DESCRIPTOR.message_types_by_name['DeleteUserRolesRequest'] = _DELETEUSERROLESREQUEST
+DESCRIPTOR.message_types_by_name['AddUserRolesRequest'] = _ADDUSERROLESREQUEST
+DESCRIPTOR.message_types_by_name['UpdateUserProfileRequest'] = _UPDATEUSERPROFILEREQUEST
+DESCRIPTOR.message_types_by_name['AddUserResponse'] = _ADDUSERRESPONSE
+DESCRIPTOR.message_types_by_name['GetOperationsMetadataRequest'] = _GETOPERATIONSMETADATAREQUEST
+DESCRIPTOR.message_types_by_name['OperationMetadata'] = _OPERATIONMETADATA
+DESCRIPTOR.message_types_by_name['GetOperationsMetadataResponse'] = _GETOPERATIONSMETADATARESPONSE
+DESCRIPTOR.message_types_by_name['DeleteTenantRequest'] = _DELETETENANTREQUEST
+DESCRIPTOR.message_types_by_name['AddRolesRequest'] = _ADDROLESREQUEST
+DESCRIPTOR.message_types_by_name['GetRolesRequest'] = _GETROLESREQUEST
+DESCRIPTOR.message_types_by_name['RoleRepresentation'] = _ROLEREPRESENTATION
+DESCRIPTOR.message_types_by_name['AllRoles'] = _ALLROLES
+DESCRIPTOR.message_types_by_name['AddProtocolMapperRequest'] = _ADDPROTOCOLMAPPERREQUEST
+DESCRIPTOR.message_types_by_name['OperationStatus'] = _OPERATIONSTATUS
+DESCRIPTOR.message_types_by_name['AddUserAttributesRequest'] = _ADDUSERATTRIBUTESREQUEST
+DESCRIPTOR.message_types_by_name['DeleteUserAttributeRequest'] = _DELETEUSERATTRIBUTEREQUEST
+DESCRIPTOR.message_types_by_name['UserAttribute'] = _USERATTRIBUTE
+DESCRIPTOR.message_types_by_name['EventPersistenceRequest'] = _EVENTPERSISTENCEREQUEST
+DESCRIPTOR.message_types_by_name['GroupsRequest'] = _GROUPSREQUEST
+DESCRIPTOR.message_types_by_name['GroupRequest'] = _GROUPREQUEST
+DESCRIPTOR.message_types_by_name['GroupsResponse'] = _GROUPSRESPONSE
+DESCRIPTOR.message_types_by_name['UserGroupMappingRequest'] = _USERGROUPMAPPINGREQUEST
+DESCRIPTOR.message_types_by_name['AgentClientMetadata'] = _AGENTCLIENTMETADATA
+DESCRIPTOR.message_types_by_name['Agent'] = _AGENT
+DESCRIPTOR.message_types_by_name['GetAllResources'] = _GETALLRESOURCES
+DESCRIPTOR.message_types_by_name['GetAllResourcesResponse'] = _GETALLRESOURCESRESPONSE
+DESCRIPTOR.enum_types_by_name['FederatedIDPs'] = _FEDERATEDIDPS
+DESCRIPTOR.enum_types_by_name['MapperTypes'] = _MAPPERTYPES
+DESCRIPTOR.enum_types_by_name['ClaimJSONTypes'] = _CLAIMJSONTYPES
+DESCRIPTOR.enum_types_by_name['ResourceTypes'] = _RESOURCETYPES
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+SetUpTenantRequest = _reflection.GeneratedProtocolMessageType('SetUpTenantRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SETUPTENANTREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.SetUpTenantRequest)
+  })
+_sym_db.RegisterMessage(SetUpTenantRequest)
+
+ConfigureFederateIDPRequest = _reflection.GeneratedProtocolMessageType('ConfigureFederateIDPRequest', (_message.Message,), {
+
+  'ConfigMapEntry' : _reflection.GeneratedProtocolMessageType('ConfigMapEntry', (_message.Message,), {
+    'DESCRIPTOR' : _CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY,
+    '__module__' : 'IamAdminService_pb2'
+    # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.ConfigureFederateIDPRequest.ConfigMapEntry)
+    })
+  ,
+  'DESCRIPTOR' : _CONFIGUREFEDERATEIDPREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.ConfigureFederateIDPRequest)
+  })
+_sym_db.RegisterMessage(ConfigureFederateIDPRequest)
+_sym_db.RegisterMessage(ConfigureFederateIDPRequest.ConfigMapEntry)
+
+FederateIDPResponse = _reflection.GeneratedProtocolMessageType('FederateIDPResponse', (_message.Message,), {
+  'DESCRIPTOR' : _FEDERATEIDPRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.FederateIDPResponse)
+  })
+_sym_db.RegisterMessage(FederateIDPResponse)
+
+SetUpTenantResponse = _reflection.GeneratedProtocolMessageType('SetUpTenantResponse', (_message.Message,), {
+  'DESCRIPTOR' : _SETUPTENANTRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.SetUpTenantResponse)
+  })
+_sym_db.RegisterMessage(SetUpTenantResponse)
+
+IsUsernameAvailableRequest = _reflection.GeneratedProtocolMessageType('IsUsernameAvailableRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ISUSERNAMEAVAILABLEREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.IsUsernameAvailableRequest)
+  })
+_sym_db.RegisterMessage(IsUsernameAvailableRequest)
+
+CheckingResponse = _reflection.GeneratedProtocolMessageType('CheckingResponse', (_message.Message,), {
+  'DESCRIPTOR' : _CHECKINGRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.CheckingResponse)
+  })
+_sym_db.RegisterMessage(CheckingResponse)
+
+UserRepresentation = _reflection.GeneratedProtocolMessageType('UserRepresentation', (_message.Message,), {
+  'DESCRIPTOR' : _USERREPRESENTATION,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserRepresentation)
+  })
+_sym_db.RegisterMessage(UserRepresentation)
+
+GroupRepresentation = _reflection.GeneratedProtocolMessageType('GroupRepresentation', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPREPRESENTATION,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GroupRepresentation)
+  })
+_sym_db.RegisterMessage(GroupRepresentation)
+
+RegisterUserRequest = _reflection.GeneratedProtocolMessageType('RegisterUserRequest', (_message.Message,), {
+  'DESCRIPTOR' : _REGISTERUSERREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RegisterUserRequest)
+  })
+_sym_db.RegisterMessage(RegisterUserRequest)
+
+RegisterUsersRequest = _reflection.GeneratedProtocolMessageType('RegisterUsersRequest', (_message.Message,), {
+  'DESCRIPTOR' : _REGISTERUSERSREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RegisterUsersRequest)
+  })
+_sym_db.RegisterMessage(RegisterUsersRequest)
+
+RegisterUserResponse = _reflection.GeneratedProtocolMessageType('RegisterUserResponse', (_message.Message,), {
+  'DESCRIPTOR' : _REGISTERUSERRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RegisterUserResponse)
+  })
+_sym_db.RegisterMessage(RegisterUserResponse)
+
+RegisterUsersResponse = _reflection.GeneratedProtocolMessageType('RegisterUsersResponse', (_message.Message,), {
+  'DESCRIPTOR' : _REGISTERUSERSRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RegisterUsersResponse)
+  })
+_sym_db.RegisterMessage(RegisterUsersResponse)
+
+UserSearchMetadata = _reflection.GeneratedProtocolMessageType('UserSearchMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _USERSEARCHMETADATA,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserSearchMetadata)
+  })
+_sym_db.RegisterMessage(UserSearchMetadata)
+
+FindUsersRequest = _reflection.GeneratedProtocolMessageType('FindUsersRequest', (_message.Message,), {
+  'DESCRIPTOR' : _FINDUSERSREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.FindUsersRequest)
+  })
+_sym_db.RegisterMessage(FindUsersRequest)
+
+UserSearchRequest = _reflection.GeneratedProtocolMessageType('UserSearchRequest', (_message.Message,), {
+  'DESCRIPTOR' : _USERSEARCHREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserSearchRequest)
+  })
+_sym_db.RegisterMessage(UserSearchRequest)
+
+FindUsersResponse = _reflection.GeneratedProtocolMessageType('FindUsersResponse', (_message.Message,), {
+  'DESCRIPTOR' : _FINDUSERSRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.FindUsersResponse)
+  })
+_sym_db.RegisterMessage(FindUsersResponse)
+
+ResetUserPassword = _reflection.GeneratedProtocolMessageType('ResetUserPassword', (_message.Message,), {
+  'DESCRIPTOR' : _RESETUSERPASSWORD,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.ResetUserPassword)
+  })
+_sym_db.RegisterMessage(ResetUserPassword)
+
+DeleteUserRolesRequest = _reflection.GeneratedProtocolMessageType('DeleteUserRolesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETEUSERROLESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.DeleteUserRolesRequest)
+  })
+_sym_db.RegisterMessage(DeleteUserRolesRequest)
+
+AddUserRolesRequest = _reflection.GeneratedProtocolMessageType('AddUserRolesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ADDUSERROLESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddUserRolesRequest)
+  })
+_sym_db.RegisterMessage(AddUserRolesRequest)
+
+UpdateUserProfileRequest = _reflection.GeneratedProtocolMessageType('UpdateUserProfileRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATEUSERPROFILEREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UpdateUserProfileRequest)
+  })
+_sym_db.RegisterMessage(UpdateUserProfileRequest)
+
+AddUserResponse = _reflection.GeneratedProtocolMessageType('AddUserResponse', (_message.Message,), {
+  'DESCRIPTOR' : _ADDUSERRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddUserResponse)
+  })
+_sym_db.RegisterMessage(AddUserResponse)
+
+GetOperationsMetadataRequest = _reflection.GeneratedProtocolMessageType('GetOperationsMetadataRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETOPERATIONSMETADATAREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetOperationsMetadataRequest)
+  })
+_sym_db.RegisterMessage(GetOperationsMetadataRequest)
+
+OperationMetadata = _reflection.GeneratedProtocolMessageType('OperationMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _OPERATIONMETADATA,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.OperationMetadata)
+  })
+_sym_db.RegisterMessage(OperationMetadata)
+
+GetOperationsMetadataResponse = _reflection.GeneratedProtocolMessageType('GetOperationsMetadataResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETOPERATIONSMETADATARESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetOperationsMetadataResponse)
+  })
+_sym_db.RegisterMessage(GetOperationsMetadataResponse)
+
+DeleteTenantRequest = _reflection.GeneratedProtocolMessageType('DeleteTenantRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETETENANTREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.DeleteTenantRequest)
+  })
+_sym_db.RegisterMessage(DeleteTenantRequest)
+
+AddRolesRequest = _reflection.GeneratedProtocolMessageType('AddRolesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ADDROLESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddRolesRequest)
+  })
+_sym_db.RegisterMessage(AddRolesRequest)
+
+GetRolesRequest = _reflection.GeneratedProtocolMessageType('GetRolesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETROLESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetRolesRequest)
+  })
+_sym_db.RegisterMessage(GetRolesRequest)
+
+RoleRepresentation = _reflection.GeneratedProtocolMessageType('RoleRepresentation', (_message.Message,), {
+  'DESCRIPTOR' : _ROLEREPRESENTATION,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.RoleRepresentation)
+  })
+_sym_db.RegisterMessage(RoleRepresentation)
+
+AllRoles = _reflection.GeneratedProtocolMessageType('AllRoles', (_message.Message,), {
+  'DESCRIPTOR' : _ALLROLES,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AllRoles)
+  })
+_sym_db.RegisterMessage(AllRoles)
+
+AddProtocolMapperRequest = _reflection.GeneratedProtocolMessageType('AddProtocolMapperRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ADDPROTOCOLMAPPERREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddProtocolMapperRequest)
+  })
+_sym_db.RegisterMessage(AddProtocolMapperRequest)
+
+OperationStatus = _reflection.GeneratedProtocolMessageType('OperationStatus', (_message.Message,), {
+  'DESCRIPTOR' : _OPERATIONSTATUS,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.OperationStatus)
+  })
+_sym_db.RegisterMessage(OperationStatus)
+
+AddUserAttributesRequest = _reflection.GeneratedProtocolMessageType('AddUserAttributesRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ADDUSERATTRIBUTESREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AddUserAttributesRequest)
+  })
+_sym_db.RegisterMessage(AddUserAttributesRequest)
+
+DeleteUserAttributeRequest = _reflection.GeneratedProtocolMessageType('DeleteUserAttributeRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETEUSERATTRIBUTEREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.DeleteUserAttributeRequest)
+  })
+_sym_db.RegisterMessage(DeleteUserAttributeRequest)
+
+UserAttribute = _reflection.GeneratedProtocolMessageType('UserAttribute', (_message.Message,), {
+  'DESCRIPTOR' : _USERATTRIBUTE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserAttribute)
+  })
+_sym_db.RegisterMessage(UserAttribute)
+
+EventPersistenceRequest = _reflection.GeneratedProtocolMessageType('EventPersistenceRequest', (_message.Message,), {
+  'DESCRIPTOR' : _EVENTPERSISTENCEREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.EventPersistenceRequest)
+  })
+_sym_db.RegisterMessage(EventPersistenceRequest)
+
+GroupsRequest = _reflection.GeneratedProtocolMessageType('GroupsRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPSREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GroupsRequest)
+  })
+_sym_db.RegisterMessage(GroupsRequest)
+
+GroupRequest = _reflection.GeneratedProtocolMessageType('GroupRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GroupRequest)
+  })
+_sym_db.RegisterMessage(GroupRequest)
+
+GroupsResponse = _reflection.GeneratedProtocolMessageType('GroupsResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GROUPSRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GroupsResponse)
+  })
+_sym_db.RegisterMessage(GroupsResponse)
+
+UserGroupMappingRequest = _reflection.GeneratedProtocolMessageType('UserGroupMappingRequest', (_message.Message,), {
+  'DESCRIPTOR' : _USERGROUPMAPPINGREQUEST,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.UserGroupMappingRequest)
+  })
+_sym_db.RegisterMessage(UserGroupMappingRequest)
+
+AgentClientMetadata = _reflection.GeneratedProtocolMessageType('AgentClientMetadata', (_message.Message,), {
+  'DESCRIPTOR' : _AGENTCLIENTMETADATA,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.AgentClientMetadata)
+  })
+_sym_db.RegisterMessage(AgentClientMetadata)
+
+Agent = _reflection.GeneratedProtocolMessageType('Agent', (_message.Message,), {
+  'DESCRIPTOR' : _AGENT,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.Agent)
+  })
+_sym_db.RegisterMessage(Agent)
+
+GetAllResources = _reflection.GeneratedProtocolMessageType('GetAllResources', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLRESOURCES,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetAllResources)
+  })
+_sym_db.RegisterMessage(GetAllResources)
+
+GetAllResourcesResponse = _reflection.GeneratedProtocolMessageType('GetAllResourcesResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETALLRESOURCESRESPONSE,
+  '__module__' : 'IamAdminService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.custos.iam.service.GetAllResourcesResponse)
+  })
+_sym_db.RegisterMessage(GetAllResourcesResponse)
+
+
+DESCRIPTOR._options = None
+_CONFIGUREFEDERATEIDPREQUEST_CONFIGMAPENTRY._options = None
+
+_IAMADMINSERVICE = _descriptor.ServiceDescriptor(
+  name='IamAdminService',
+  full_name='org.apache.custos.iam.service.IamAdminService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=6638,
+  serialized_end=12271,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='setUPTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.setUPTenant',
+    index=0,
+    containing_service=None,
+    input_type=_SETUPTENANTREQUEST,
+    output_type=_SETUPTENANTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.updateTenant',
+    index=1,
+    containing_service=None,
+    input_type=_SETUPTENANTREQUEST,
+    output_type=_SETUPTENANTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteTenant',
+    index=2,
+    containing_service=None,
+    input_type=_DELETETENANTREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='configureFederatedIDP',
+    full_name='org.apache.custos.iam.service.IamAdminService.configureFederatedIDP',
+    index=3,
+    containing_service=None,
+    input_type=_CONFIGUREFEDERATEIDPREQUEST,
+    output_type=_FEDERATEIDPRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addRolesToTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.addRolesToTenant',
+    index=4,
+    containing_service=None,
+    input_type=_ADDROLESREQUEST,
+    output_type=_ALLROLES,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addProtocolMapper',
+    full_name='org.apache.custos.iam.service.IamAdminService.addProtocolMapper',
+    index=5,
+    containing_service=None,
+    input_type=_ADDPROTOCOLMAPPERREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getRolesOfTenant',
+    full_name='org.apache.custos.iam.service.IamAdminService.getRolesOfTenant',
+    index=6,
+    containing_service=None,
+    input_type=_GETROLESREQUEST,
+    output_type=_ALLROLES,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isUsernameAvailable',
+    full_name='org.apache.custos.iam.service.IamAdminService.isUsernameAvailable',
+    index=7,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='registerUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.registerUser',
+    index=8,
+    containing_service=None,
+    input_type=_REGISTERUSERREQUEST,
+    output_type=_REGISTERUSERRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='enableUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.enableUser',
+    index=9,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_USERREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='disableUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.disableUser',
+    index=10,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_USERREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isUserEnabled',
+    full_name='org.apache.custos.iam.service.IamAdminService.isUserEnabled',
+    index=11,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isUserExist',
+    full_name='org.apache.custos.iam.service.IamAdminService.isUserExist',
+    index=12,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_CHECKINGRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.getUser',
+    index=13,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_USERREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='findUsers',
+    full_name='org.apache.custos.iam.service.IamAdminService.findUsers',
+    index=14,
+    containing_service=None,
+    input_type=_FINDUSERSREQUEST,
+    output_type=_FINDUSERSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='resetPassword',
+    full_name='org.apache.custos.iam.service.IamAdminService.resetPassword',
+    index=15,
+    containing_service=None,
+    input_type=_RESETUSERPASSWORD,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='grantAdminPrivilege',
+    full_name='org.apache.custos.iam.service.IamAdminService.grantAdminPrivilege',
+    index=16,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeAdminPrivilege',
+    full_name='org.apache.custos.iam.service.IamAdminService.removeAdminPrivilege',
+    index=17,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='registerAndEnableUsers',
+    full_name='org.apache.custos.iam.service.IamAdminService.registerAndEnableUsers',
+    index=18,
+    containing_service=None,
+    input_type=_REGISTERUSERSREQUEST,
+    output_type=_REGISTERUSERSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addUserAttributes',
+    full_name='org.apache.custos.iam.service.IamAdminService.addUserAttributes',
+    index=19,
+    containing_service=None,
+    input_type=_ADDUSERATTRIBUTESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteUserAttributes',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteUserAttributes',
+    index=20,
+    containing_service=None,
+    input_type=_DELETEUSERATTRIBUTEREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addRolesToUsers',
+    full_name='org.apache.custos.iam.service.IamAdminService.addRolesToUsers',
+    index=21,
+    containing_service=None,
+    input_type=_ADDUSERROLESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteUser',
+    index=22,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteRolesFromUser',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteRolesFromUser',
+    index=23,
+    containing_service=None,
+    input_type=_DELETEUSERROLESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateUserProfile',
+    full_name='org.apache.custos.iam.service.IamAdminService.updateUserProfile',
+    index=24,
+    containing_service=None,
+    input_type=_UPDATEUSERPROFILEREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getOperationMetadata',
+    full_name='org.apache.custos.iam.service.IamAdminService.getOperationMetadata',
+    index=25,
+    containing_service=None,
+    input_type=_GETOPERATIONSMETADATAREQUEST,
+    output_type=_GETOPERATIONSMETADATARESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='configureEventPersistence',
+    full_name='org.apache.custos.iam.service.IamAdminService.configureEventPersistence',
+    index=26,
+    containing_service=None,
+    input_type=_EVENTPERSISTENCEREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createGroups',
+    full_name='org.apache.custos.iam.service.IamAdminService.createGroups',
+    index=27,
+    containing_service=None,
+    input_type=_GROUPSREQUEST,
+    output_type=_GROUPSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.updateGroup',
+    index=28,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUPREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteGroup',
+    index=29,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='findGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.findGroup',
+    index=30,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUPREPRESENTATION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllGroups',
+    full_name='org.apache.custos.iam.service.IamAdminService.getAllGroups',
+    index=31,
+    containing_service=None,
+    input_type=_GROUPREQUEST,
+    output_type=_GROUPSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addUserToGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.addUserToGroup',
+    index=32,
+    containing_service=None,
+    input_type=_USERGROUPMAPPINGREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='removeUserFromGroup',
+    full_name='org.apache.custos.iam.service.IamAdminService.removeUserFromGroup',
+    index=33,
+    containing_service=None,
+    input_type=_USERGROUPMAPPINGREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='createAgentClient',
+    full_name='org.apache.custos.iam.service.IamAdminService.createAgentClient',
+    index=34,
+    containing_service=None,
+    input_type=_AGENTCLIENTMETADATA,
+    output_type=_SETUPTENANTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='configureAgentClient',
+    full_name='org.apache.custos.iam.service.IamAdminService.configureAgentClient',
+    index=35,
+    containing_service=None,
+    input_type=_AGENTCLIENTMETADATA,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='isAgentNameAvailable',
+    full_name='org.apache.custos.iam.service.IamAdminService.isAgentNameAvailable',
+    index=36,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='registerAndEnableAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.registerAndEnableAgent',
+    index=37,
+    containing_service=None,
+    input_type=_REGISTERUSERREQUEST,
+    output_type=_REGISTERUSERRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteAgent',
+    index=38,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.getAgent',
+    index=39,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_AGENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='disableAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.disableAgent',
+    index=40,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='enableAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.enableAgent',
+    index=41,
+    containing_service=None,
+    input_type=_USERSEARCHREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addAgentAttributes',
+    full_name='org.apache.custos.iam.service.IamAdminService.addAgentAttributes',
+    index=42,
+    containing_service=None,
+    input_type=_ADDUSERATTRIBUTESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgentAttributes',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteAgentAttributes',
+    index=43,
+    containing_service=None,
+    input_type=_DELETEUSERATTRIBUTEREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='addRolesToAgent',
+    full_name='org.apache.custos.iam.service.IamAdminService.addRolesToAgent',
+    index=44,
+    containing_service=None,
+    input_type=_ADDUSERROLESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteAgentRoles',
+    full_name='org.apache.custos.iam.service.IamAdminService.deleteAgentRoles',
+    index=45,
+    containing_service=None,
+    input_type=_DELETEUSERROLESREQUEST,
+    output_type=_OPERATIONSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='getAllResources',
+    full_name='org.apache.custos.iam.service.IamAdminService.getAllResources',
+    index=46,
+    containing_service=None,
+    input_type=_GETALLRESOURCES,
+    output_type=_GETALLRESOURCESRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_IAMADMINSERVICE)
+
+DESCRIPTOR.services_by_name['IamAdminService'] = _IAMADMINSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/custos-core-services/iam-admin-core-service/IamAdminService_pb2_grpc.py b/custos-core-services/iam-admin-core-service/IamAdminService_pb2_grpc.py
new file mode 100644
index 0000000..ae910ef
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/IamAdminService_pb2_grpc.py
@@ -0,0 +1,1585 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import IamAdminService_pb2 as IamAdminService__pb2
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+
+
+class IamAdminServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.setUPTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/setUPTenant',
+                request_serializer=IamAdminService__pb2.SetUpTenantRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.SetUpTenantResponse.FromString,
+                )
+        self.updateTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/updateTenant',
+                request_serializer=IamAdminService__pb2.SetUpTenantRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.SetUpTenantResponse.FromString,
+                )
+        self.deleteTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteTenant',
+                request_serializer=IamAdminService__pb2.DeleteTenantRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.configureFederatedIDP = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/configureFederatedIDP',
+                request_serializer=IamAdminService__pb2.ConfigureFederateIDPRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.FederateIDPResponse.FromString,
+                )
+        self.addRolesToTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addRolesToTenant',
+                request_serializer=IamAdminService__pb2.AddRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.AllRoles.FromString,
+                )
+        self.addProtocolMapper = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addProtocolMapper',
+                request_serializer=IamAdminService__pb2.AddProtocolMapperRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getRolesOfTenant = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getRolesOfTenant',
+                request_serializer=IamAdminService__pb2.GetRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.AllRoles.FromString,
+                )
+        self.isUsernameAvailable = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/isUsernameAvailable',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.registerUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/registerUser',
+                request_serializer=IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.RegisterUserResponse.FromString,
+                )
+        self.enableUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/enableUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.UserRepresentation.FromString,
+                )
+        self.disableUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/disableUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.UserRepresentation.FromString,
+                )
+        self.isUserEnabled = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/isUserEnabled',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.isUserExist = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/isUserExist',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.CheckingResponse.FromString,
+                )
+        self.getUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.UserRepresentation.FromString,
+                )
+        self.findUsers = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/findUsers',
+                request_serializer=IamAdminService__pb2.FindUsersRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.FindUsersResponse.FromString,
+                )
+        self.resetPassword = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/resetPassword',
+                request_serializer=IamAdminService__pb2.ResetUserPassword.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.grantAdminPrivilege = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/grantAdminPrivilege',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.removeAdminPrivilege = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/removeAdminPrivilege',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.registerAndEnableUsers = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/registerAndEnableUsers',
+                request_serializer=IamAdminService__pb2.RegisterUsersRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.RegisterUsersResponse.FromString,
+                )
+        self.addUserAttributes = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addUserAttributes',
+                request_serializer=IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteUserAttributes = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteUserAttributes',
+                request_serializer=IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.addRolesToUsers = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addRolesToUsers',
+                request_serializer=IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteUser',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteRolesFromUser = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteRolesFromUser',
+                request_serializer=IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.updateUserProfile = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/updateUserProfile',
+                request_serializer=IamAdminService__pb2.UpdateUserProfileRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getOperationMetadata = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getOperationMetadata',
+                request_serializer=IamAdminService__pb2.GetOperationsMetadataRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GetOperationsMetadataResponse.FromString,
+                )
+        self.configureEventPersistence = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/configureEventPersistence',
+                request_serializer=IamAdminService__pb2.EventPersistenceRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.createGroups = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/createGroups',
+                request_serializer=IamAdminService__pb2.GroupsRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupsResponse.FromString,
+                )
+        self.updateGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/updateGroup',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupRepresentation.FromString,
+                )
+        self.deleteGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteGroup',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.findGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/findGroup',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupRepresentation.FromString,
+                )
+        self.getAllGroups = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getAllGroups',
+                request_serializer=IamAdminService__pb2.GroupRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GroupsResponse.FromString,
+                )
+        self.addUserToGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addUserToGroup',
+                request_serializer=IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.removeUserFromGroup = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/removeUserFromGroup',
+                request_serializer=IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.createAgentClient = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/createAgentClient',
+                request_serializer=IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+                response_deserializer=IamAdminService__pb2.SetUpTenantResponse.FromString,
+                )
+        self.configureAgentClient = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/configureAgentClient',
+                request_serializer=IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.isAgentNameAvailable = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/isAgentNameAvailable',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.registerAndEnableAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/registerAndEnableAgent',
+                request_serializer=IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.RegisterUserResponse.FromString,
+                )
+        self.deleteAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteAgent',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getAgent',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.Agent.FromString,
+                )
+        self.disableAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/disableAgent',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.enableAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/enableAgent',
+                request_serializer=IamAdminService__pb2.UserSearchRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.addAgentAttributes = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addAgentAttributes',
+                request_serializer=IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteAgentAttributes = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteAgentAttributes',
+                request_serializer=IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.addRolesToAgent = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/addRolesToAgent',
+                request_serializer=IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.deleteAgentRoles = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/deleteAgentRoles',
+                request_serializer=IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+                response_deserializer=IamAdminService__pb2.OperationStatus.FromString,
+                )
+        self.getAllResources = channel.unary_unary(
+                '/org.apache.custos.iam.service.IamAdminService/getAllResources',
+                request_serializer=IamAdminService__pb2.GetAllResources.SerializeToString,
+                response_deserializer=IamAdminService__pb2.GetAllResourcesResponse.FromString,
+                )
+
+
+class IamAdminServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def setUPTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def configureFederatedIDP(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addRolesToTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addProtocolMapper(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getRolesOfTenant(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isUsernameAvailable(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def registerUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def enableUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def disableUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isUserEnabled(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isUserExist(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def findUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def resetPassword(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def grantAdminPrivilege(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeAdminPrivilege(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def registerAndEnableUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addUserAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteUserAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addRolesToUsers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteRolesFromUser(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateUserProfile(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getOperationMetadata(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def configureEventPersistence(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def createGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def updateGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def findGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllGroups(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addUserToGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def removeUserFromGroup(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def createAgentClient(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def configureAgentClient(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def isAgentNameAvailable(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def registerAndEnableAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def disableAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def enableAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addAgentAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteAgentAttributes(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def addRolesToAgent(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def deleteAgentRoles(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def getAllResources(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_IamAdminServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'setUPTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.setUPTenant,
+                    request_deserializer=IamAdminService__pb2.SetUpTenantRequest.FromString,
+                    response_serializer=IamAdminService__pb2.SetUpTenantResponse.SerializeToString,
+            ),
+            'updateTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateTenant,
+                    request_deserializer=IamAdminService__pb2.SetUpTenantRequest.FromString,
+                    response_serializer=IamAdminService__pb2.SetUpTenantResponse.SerializeToString,
+            ),
+            'deleteTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteTenant,
+                    request_deserializer=IamAdminService__pb2.DeleteTenantRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'configureFederatedIDP': grpc.unary_unary_rpc_method_handler(
+                    servicer.configureFederatedIDP,
+                    request_deserializer=IamAdminService__pb2.ConfigureFederateIDPRequest.FromString,
+                    response_serializer=IamAdminService__pb2.FederateIDPResponse.SerializeToString,
+            ),
+            'addRolesToTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.addRolesToTenant,
+                    request_deserializer=IamAdminService__pb2.AddRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.AllRoles.SerializeToString,
+            ),
+            'addProtocolMapper': grpc.unary_unary_rpc_method_handler(
+                    servicer.addProtocolMapper,
+                    request_deserializer=IamAdminService__pb2.AddProtocolMapperRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getRolesOfTenant': grpc.unary_unary_rpc_method_handler(
+                    servicer.getRolesOfTenant,
+                    request_deserializer=IamAdminService__pb2.GetRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.AllRoles.SerializeToString,
+            ),
+            'isUsernameAvailable': grpc.unary_unary_rpc_method_handler(
+                    servicer.isUsernameAvailable,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'registerUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.registerUser,
+                    request_deserializer=IamAdminService__pb2.RegisterUserRequest.FromString,
+                    response_serializer=IamAdminService__pb2.RegisterUserResponse.SerializeToString,
+            ),
+            'enableUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.enableUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.UserRepresentation.SerializeToString,
+            ),
+            'disableUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.disableUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.UserRepresentation.SerializeToString,
+            ),
+            'isUserEnabled': grpc.unary_unary_rpc_method_handler(
+                    servicer.isUserEnabled,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'isUserExist': grpc.unary_unary_rpc_method_handler(
+                    servicer.isUserExist,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.CheckingResponse.SerializeToString,
+            ),
+            'getUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.getUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.UserRepresentation.SerializeToString,
+            ),
+            'findUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.findUsers,
+                    request_deserializer=IamAdminService__pb2.FindUsersRequest.FromString,
+                    response_serializer=IamAdminService__pb2.FindUsersResponse.SerializeToString,
+            ),
+            'resetPassword': grpc.unary_unary_rpc_method_handler(
+                    servicer.resetPassword,
+                    request_deserializer=IamAdminService__pb2.ResetUserPassword.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'grantAdminPrivilege': grpc.unary_unary_rpc_method_handler(
+                    servicer.grantAdminPrivilege,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'removeAdminPrivilege': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeAdminPrivilege,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'registerAndEnableUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.registerAndEnableUsers,
+                    request_deserializer=IamAdminService__pb2.RegisterUsersRequest.FromString,
+                    response_serializer=IamAdminService__pb2.RegisterUsersResponse.SerializeToString,
+            ),
+            'addUserAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.addUserAttributes,
+                    request_deserializer=IamAdminService__pb2.AddUserAttributesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteUserAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteUserAttributes,
+                    request_deserializer=IamAdminService__pb2.DeleteUserAttributeRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'addRolesToUsers': grpc.unary_unary_rpc_method_handler(
+                    servicer.addRolesToUsers,
+                    request_deserializer=IamAdminService__pb2.AddUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteUser,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteRolesFromUser': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteRolesFromUser,
+                    request_deserializer=IamAdminService__pb2.DeleteUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'updateUserProfile': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateUserProfile,
+                    request_deserializer=IamAdminService__pb2.UpdateUserProfileRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getOperationMetadata': grpc.unary_unary_rpc_method_handler(
+                    servicer.getOperationMetadata,
+                    request_deserializer=IamAdminService__pb2.GetOperationsMetadataRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GetOperationsMetadataResponse.SerializeToString,
+            ),
+            'configureEventPersistence': grpc.unary_unary_rpc_method_handler(
+                    servicer.configureEventPersistence,
+                    request_deserializer=IamAdminService__pb2.EventPersistenceRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'createGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.createGroups,
+                    request_deserializer=IamAdminService__pb2.GroupsRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupsResponse.SerializeToString,
+            ),
+            'updateGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.updateGroup,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupRepresentation.SerializeToString,
+            ),
+            'deleteGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteGroup,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'findGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.findGroup,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupRepresentation.SerializeToString,
+            ),
+            'getAllGroups': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllGroups,
+                    request_deserializer=IamAdminService__pb2.GroupRequest.FromString,
+                    response_serializer=IamAdminService__pb2.GroupsResponse.SerializeToString,
+            ),
+            'addUserToGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.addUserToGroup,
+                    request_deserializer=IamAdminService__pb2.UserGroupMappingRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'removeUserFromGroup': grpc.unary_unary_rpc_method_handler(
+                    servicer.removeUserFromGroup,
+                    request_deserializer=IamAdminService__pb2.UserGroupMappingRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'createAgentClient': grpc.unary_unary_rpc_method_handler(
+                    servicer.createAgentClient,
+                    request_deserializer=IamAdminService__pb2.AgentClientMetadata.FromString,
+                    response_serializer=IamAdminService__pb2.SetUpTenantResponse.SerializeToString,
+            ),
+            'configureAgentClient': grpc.unary_unary_rpc_method_handler(
+                    servicer.configureAgentClient,
+                    request_deserializer=IamAdminService__pb2.AgentClientMetadata.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'isAgentNameAvailable': grpc.unary_unary_rpc_method_handler(
+                    servicer.isAgentNameAvailable,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'registerAndEnableAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.registerAndEnableAgent,
+                    request_deserializer=IamAdminService__pb2.RegisterUserRequest.FromString,
+                    response_serializer=IamAdminService__pb2.RegisterUserResponse.SerializeToString,
+            ),
+            'deleteAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteAgent,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAgent,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.Agent.SerializeToString,
+            ),
+            'disableAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.disableAgent,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'enableAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.enableAgent,
+                    request_deserializer=IamAdminService__pb2.UserSearchRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'addAgentAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.addAgentAttributes,
+                    request_deserializer=IamAdminService__pb2.AddUserAttributesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteAgentAttributes': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteAgentAttributes,
+                    request_deserializer=IamAdminService__pb2.DeleteUserAttributeRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'addRolesToAgent': grpc.unary_unary_rpc_method_handler(
+                    servicer.addRolesToAgent,
+                    request_deserializer=IamAdminService__pb2.AddUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'deleteAgentRoles': grpc.unary_unary_rpc_method_handler(
+                    servicer.deleteAgentRoles,
+                    request_deserializer=IamAdminService__pb2.DeleteUserRolesRequest.FromString,
+                    response_serializer=IamAdminService__pb2.OperationStatus.SerializeToString,
+            ),
+            'getAllResources': grpc.unary_unary_rpc_method_handler(
+                    servicer.getAllResources,
+                    request_deserializer=IamAdminService__pb2.GetAllResources.FromString,
+                    response_serializer=IamAdminService__pb2.GetAllResourcesResponse.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'org.apache.custos.iam.service.IamAdminService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class IamAdminService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def setUPTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/setUPTenant',
+            IamAdminService__pb2.SetUpTenantRequest.SerializeToString,
+            IamAdminService__pb2.SetUpTenantResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/updateTenant',
+            IamAdminService__pb2.SetUpTenantRequest.SerializeToString,
+            IamAdminService__pb2.SetUpTenantResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteTenant',
+            IamAdminService__pb2.DeleteTenantRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def configureFederatedIDP(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/configureFederatedIDP',
+            IamAdminService__pb2.ConfigureFederateIDPRequest.SerializeToString,
+            IamAdminService__pb2.FederateIDPResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addRolesToTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addRolesToTenant',
+            IamAdminService__pb2.AddRolesRequest.SerializeToString,
+            IamAdminService__pb2.AllRoles.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addProtocolMapper(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addProtocolMapper',
+            IamAdminService__pb2.AddProtocolMapperRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getRolesOfTenant(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getRolesOfTenant',
+            IamAdminService__pb2.GetRolesRequest.SerializeToString,
+            IamAdminService__pb2.AllRoles.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isUsernameAvailable(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/isUsernameAvailable',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def registerUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/registerUser',
+            IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+            IamAdminService__pb2.RegisterUserResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def enableUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/enableUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.UserRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def disableUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/disableUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.UserRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isUserEnabled(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/isUserEnabled',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isUserExist(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/isUserExist',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.CheckingResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.UserRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def findUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/findUsers',
+            IamAdminService__pb2.FindUsersRequest.SerializeToString,
+            IamAdminService__pb2.FindUsersResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def resetPassword(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/resetPassword',
+            IamAdminService__pb2.ResetUserPassword.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def grantAdminPrivilege(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/grantAdminPrivilege',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeAdminPrivilege(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/removeAdminPrivilege',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def registerAndEnableUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/registerAndEnableUsers',
+            IamAdminService__pb2.RegisterUsersRequest.SerializeToString,
+            IamAdminService__pb2.RegisterUsersResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addUserAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addUserAttributes',
+            IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteUserAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteUserAttributes',
+            IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addRolesToUsers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addRolesToUsers',
+            IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteUser',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteRolesFromUser(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteRolesFromUser',
+            IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateUserProfile(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/updateUserProfile',
+            IamAdminService__pb2.UpdateUserProfileRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getOperationMetadata(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getOperationMetadata',
+            IamAdminService__pb2.GetOperationsMetadataRequest.SerializeToString,
+            IamAdminService__pb2.GetOperationsMetadataResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def configureEventPersistence(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/configureEventPersistence',
+            IamAdminService__pb2.EventPersistenceRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def createGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/createGroups',
+            IamAdminService__pb2.GroupsRequest.SerializeToString,
+            IamAdminService__pb2.GroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def updateGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/updateGroup',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.GroupRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteGroup',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def findGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/findGroup',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.GroupRepresentation.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllGroups(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getAllGroups',
+            IamAdminService__pb2.GroupRequest.SerializeToString,
+            IamAdminService__pb2.GroupsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addUserToGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addUserToGroup',
+            IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def removeUserFromGroup(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/removeUserFromGroup',
+            IamAdminService__pb2.UserGroupMappingRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def createAgentClient(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/createAgentClient',
+            IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+            IamAdminService__pb2.SetUpTenantResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def configureAgentClient(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/configureAgentClient',
+            IamAdminService__pb2.AgentClientMetadata.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def isAgentNameAvailable(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/isAgentNameAvailable',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def registerAndEnableAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/registerAndEnableAgent',
+            IamAdminService__pb2.RegisterUserRequest.SerializeToString,
+            IamAdminService__pb2.RegisterUserResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteAgent',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getAgent',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.Agent.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def disableAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/disableAgent',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def enableAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/enableAgent',
+            IamAdminService__pb2.UserSearchRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addAgentAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addAgentAttributes',
+            IamAdminService__pb2.AddUserAttributesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteAgentAttributes(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteAgentAttributes',
+            IamAdminService__pb2.DeleteUserAttributeRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def addRolesToAgent(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/addRolesToAgent',
+            IamAdminService__pb2.AddUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def deleteAgentRoles(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/deleteAgentRoles',
+            IamAdminService__pb2.DeleteUserRolesRequest.SerializeToString,
+            IamAdminService__pb2.OperationStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def getAllResources(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/org.apache.custos.iam.service.IamAdminService/getAllResources',
+            IamAdminService__pb2.GetAllResources.SerializeToString,
+            IamAdminService__pb2.GetAllResourcesResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/custos-core-services/iam-admin-core-service/pom.xml b/custos-core-services/iam-admin-core-service/pom.xml
new file mode 100644
index 0000000..5201c4c
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/pom.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>iam-admin-core-service</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-federated-services-clients</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/.helmignore b/custos-core-services/iam-admin-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/Chart.yaml b/custos-core-services/iam-admin-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..5f4930b
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of custos IAM service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/iam-admin-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/iam-admin-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/iam-admin-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..31e54a6
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,64 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/iam-admin-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/templates/service.yaml b/custos-core-services/iam-admin-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/iam-admin-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/iam-admin-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/iam-admin-core-service/src/main/helm/values.yaml b/custos-core-services/iam-admin-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..93eb74d
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/helm/values.yaml
@@ -0,0 +1,78 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/IamServiceInitializer.java b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/IamServiceInitializer.java
new file mode 100644
index 0000000..37bb5ce
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/IamServiceInitializer.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.iam;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.apache.custos.iam.validator.InputValidator;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableJpaRepositories(basePackages = "org.apache.custos")
+@ComponentScan(basePackages = "org.apache.custos")
+@EntityScan(basePackages = "org.apache.custos")
+public class IamServiceInitializer {
+
+    public static void main(String[] args) {
+        SpringApplication.run(IamServiceInitializer.class, args);
+    }
+
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator){
+        return new ServiceInterceptor(validator);
+    }
+}
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/exceptions/MissingParameterException.java b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/exceptions/MissingParameterException.java
new file mode 100644
index 0000000..3f7e965
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/exceptions/MissingParameterException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.iam.exceptions;
+
+/**
+ * Missing Parameter
+ */
+public class MissingParameterException extends RuntimeException {
+
+   public MissingParameterException(String msg, Throwable e) {
+      super(msg,e);
+   }
+}
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/service/IamAdminService.java b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/service/IamAdminService.java
new file mode 100644
index 0000000..d6b4702
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/service/IamAdminService.java
@@ -0,0 +1,2372 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.iam.service;
+
+import com.google.protobuf.Empty;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.core.services.commons.StatusUpdater;
+import org.apache.custos.core.services.commons.persistance.model.OperationStatus;
+import org.apache.custos.core.services.commons.persistance.model.StatusEntity;
+import org.apache.custos.core.services.commons.util.Constants;
+import org.apache.custos.federated.services.clients.keycloak.KeycloakClient;
+import org.apache.custos.federated.services.clients.keycloak.KeycloakClientSecret;
+import org.apache.custos.federated.services.clients.keycloak.UnauthorizedException;
+import org.apache.custos.iam.service.IamAdminServiceGrpc.IamAdminServiceImplBase;
+import org.apache.custos.iam.utils.IAMOperations;
+import org.apache.custos.iam.utils.Status;
+import org.keycloak.representations.idm.EventRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.representations.idm.UserSessionRepresentation;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@GRpcService
+public class IamAdminService extends IamAdminServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(IamAdminService.class);
+
+    @Autowired
+    private KeycloakClient keycloakClient;
+
+    @Autowired
+    private StatusUpdater statusUpdater;
+
+    @Override
+    public void setUPTenant(SetUpTenantRequest request, StreamObserver<SetUpTenantResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to setUPTenant  " + request.getTenantId());
+
+            keycloakClient.deleteRealm(String.valueOf(request.getTenantId()));
+
+            keycloakClient.createRealm(String.valueOf(request.getTenantId()), request.getTenantName());
+
+            keycloakClient.createRealmAdminAccount(String.valueOf(request.getTenantId()), request.getAdminUsername(),
+                    request.getAdminFirstname(), request.getAdminLastname(),
+                    request.getAdminEmail(), request.getAdminPassword());
+
+            KeycloakClientSecret clientSecret = keycloakClient.configureClient(String.valueOf(request.getTenantId()),
+                    request.getCustosClientId(),
+                    request.getTenantURL(), request.getRedirectURIsList());
+
+            SetUpTenantResponse response = SetUpTenantResponse.newBuilder()
+                    .setClientId(clientSecret.getClientId())
+                    .setClientSecret(clientSecret.getClientSecret())
+                    .build();
+
+
+            statusUpdater.updateStatus(IAMOperations.SET_UP_TENANT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getRequesterEmail());
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during setUPTenant" + ex;
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.SET_UP_TENANT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getRequesterEmail());
+
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void updateTenant(SetUpTenantRequest request, StreamObserver<SetUpTenantResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateTenant  " + request.getTenantId());
+
+            keycloakClient.updateRealm(String.valueOf(request.getTenantId()), request.getTenantName());
+
+            keycloakClient.updateRealmAdminAccount(String.valueOf(request.getTenantId()), request.getAdminUsername(),
+                    request.getAdminFirstname(), request.getAdminLastname(),
+                    request.getAdminEmail(), request.getAdminPassword());
+
+            KeycloakClientSecret clientSecret = keycloakClient.updateClient(String.valueOf(request.getTenantId()),
+                    request.getCustosClientId(),
+                    request.getTenantURL(), request.getRedirectURIsList());
+
+            SetUpTenantResponse response = SetUpTenantResponse.newBuilder()
+                    .setClientId(clientSecret.getClientId())
+                    .setClientSecret(clientSecret.getClientSecret())
+                    .build();
+
+
+            statusUpdater.updateStatus(IAMOperations.UPDATE_TENANT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getRequesterEmail());
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during updateTenant" + ex;
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.UPDATE_TENANT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getRequesterEmail());
+
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteTenant(DeleteTenantRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            LOGGER.debug("Request received to delete tenant  " + request.getTenantId());
+
+            keycloakClient.deleteRealm(String.valueOf(request.getTenantId()));
+
+            responseObserver.onNext(Empty.newBuilder().build());
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during delete tenant" + ex;
+            LOGGER.error(msg, ex);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void isUsernameAvailable(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to isUsernameAvailable at " + request.getTenantId());
+
+            boolean isAvailable = keycloakClient.isUsernameAvailable(String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(),
+                    request.getAccessToken());
+
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus.
+                    newBuilder().setStatus(isAvailable).build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during isUsernameAvailable" + ex;
+            LOGGER.error(msg, ex);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void isUserEnabled(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to isUserEnabled at " + request.getTenantId());
+
+            boolean isAvailable = keycloakClient.isUserAccountEnabled(String.valueOf(request.getTenantId()),
+                    request.getAccessToken(),
+                    request.getUser().getUsername());
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus.
+                    newBuilder().setStatus(isAvailable).build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during isUserEnabled" + ex;
+            LOGGER.error(msg, ex);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void registerUser(RegisterUserRequest request, StreamObserver<RegisterUserResponse> responseObserver) {
+
+        try {
+            LOGGER.debug("Request received to registerUser for " + request.getTenantId());
+
+            boolean registered = keycloakClient.createUser(String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(),
+                    request.getUser().getPassword(),
+                    request.getUser().getFirstName(),
+                    request.getUser().getLastName(),
+                    request.getUser().getEmail(),
+                    request.getUser().getTemporaryPassword(),
+                    request.getAccessToken());
+
+
+            RegisterUserResponse registerUserResponse = RegisterUserResponse.newBuilder().
+                    setIsRegistered(registered).build();
+
+
+            statusUpdater.updateStatus(IAMOperations.REGISTER_USER.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+
+            responseObserver.onNext(registerUserResponse);
+            responseObserver.onCompleted();
+
+        } catch (UnauthorizedException ex) {
+            String msg = "Error occurred during registerUser" + ex;
+            statusUpdater.updateStatus(IAMOperations.REGISTER_USER.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+            responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+        } catch (Exception ex) {
+            String msg = "Error occurred during registerUser" + ex;
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.REGISTER_USER.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void enableUser(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.UserRepresentation> responseObserver) {
+
+        try {
+            LOGGER.debug("Request received to enableUser for " + request.getTenantId());
+
+            boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(), request.getAccessToken());
+
+            if (!status) {
+                statusUpdater.updateStatus(IAMOperations.ENABLE_USER.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(),
+                        String.valueOf(request.getTenantId()));
+
+                String msg = "User not valid ";
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            boolean accountEnabled = keycloakClient.enableUserAccount(String.valueOf(request.getTenantId()),
+                    request.getAccessToken(), request.getUser().getUsername());
+            if (accountEnabled) {
+
+                UserRepresentation representation = keycloakClient.getUser(String.valueOf(request.getTenantId()),
+                        request.getAccessToken(), request.getUser().getUsername());
+
+                org.apache.custos.iam.service.UserRepresentation user = getUser(representation, request.getClientId());
+
+
+                statusUpdater.updateStatus(IAMOperations.ENABLE_USER.name(),
+                        OperationStatus.SUCCESS,
+                        request.getTenantId(),
+                        String.valueOf(request.getTenantId()));
+
+
+                responseObserver.onNext(user);
+                responseObserver.onCompleted();
+
+            } else {
+
+                statusUpdater.updateStatus(IAMOperations.ENABLE_USER.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(),
+                        String.valueOf(request.getTenantId()));
+
+                String msg = "Account enabling failed ";
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during enableUser" + ex;
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.ENABLE_USER.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void disableUser(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.UserRepresentation> responseObserver) {
+        try {
+            LOGGER.debug("Request received to disable for " + request.getTenantId());
+
+            boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(), request.getAccessToken());
+
+
+            if (!status) {
+                statusUpdater.updateStatus(IAMOperations.DISABLE_USER.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(),
+                        String.valueOf(request.getTenantId()));
+
+                String msg = "User not valid ";
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            boolean accountDisabled = keycloakClient.disableUserAccount(String.valueOf(request.getTenantId()),
+                    request.getAccessToken(), request.getUser().getUsername());
+            if (accountDisabled) {
+
+                UserRepresentation representation = keycloakClient.getUser(String.valueOf(request.getTenantId()),
+                        request.getAccessToken(), request.getUser().getUsername());
+
+                org.apache.custos.iam.service.UserRepresentation user = getUser(representation, request.getClientId());
+
+
+                statusUpdater.updateStatus(IAMOperations.DISABLE_USER.name(),
+                        OperationStatus.SUCCESS,
+                        request.getTenantId(),
+                        String.valueOf(request.getTenantId()));
+
+
+                responseObserver.onNext(user);
+                responseObserver.onCompleted();
+
+            } else {
+
+                statusUpdater.updateStatus(IAMOperations.DISABLE_USER.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(),
+                        String.valueOf(request.getTenantId()));
+
+                String msg = "Account enabling failed ";
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during disabling user" + ex;
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.DISABLE_USER.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void isUserExist(UserSearchRequest request, StreamObserver<CheckingResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to isUserExist for " + request.getTenantId());
+
+
+            boolean isUserExist = keycloakClient.isUserExist(String.valueOf(request.getTenantId()),
+                    request.getAccessToken(), request.getUser().getUsername());
+            CheckingResponse response = CheckingResponse.newBuilder().setIsExist(isUserExist).build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during isUserExist" + ex;
+            LOGGER.error(msg, ex);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getUser(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.UserRepresentation> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getUser for " + request.getTenantId());
+
+
+            boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(), request.getAccessToken());
+
+
+            if (!status) {
+                String msg = "User " + request.getUser().getUsername() + "not found at " + request.getTenantId();
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            UserRepresentation representation = keycloakClient.getUser(String.valueOf(request.getTenantId()),
+                    request.getAccessToken(), request.getUser().getUsername());
+
+            if (representation != null) {
+                org.apache.custos.iam.service.UserRepresentation user = getUser(representation, request.getClientId());
+
+                UserSessionRepresentation sessionRepresentation = keycloakClient.getLatestSession(String.valueOf(request.getTenantId()),
+                        request.getClientId(), request.getAccessToken(), request.getUser().getUsername());
+
+                if (sessionRepresentation != null) {
+                    user = user.toBuilder().setLastLoginAt(sessionRepresentation.getLastAccess()).build();
+                } else {
+                    EventRepresentation eventRepresentation = keycloakClient.
+                            getLastLoginEvent(String.valueOf(request.getTenantId()), request.getClientId()
+                                    , request.getUser().getUsername());
+                    if (eventRepresentation != null) {
+                        user = user.toBuilder().setLastLoginAt(eventRepresentation.getTime()).build();
+                    }
+                }
+                responseObserver.onNext(user);
+                responseObserver.onCompleted();
+            } else {
+                String msg = "User " + request.getUser().getUsername() + " not found in " + request.getTenantId();
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during getUser" + ex;
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void findUsers(FindUsersRequest request, StreamObserver<FindUsersResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getUsers for " + request.getUser().getUsername());
+
+            List<UserRepresentation> representation = keycloakClient.getUsers(request.getAccessToken(),
+                    String.valueOf(request.getTenantId()), request.getOffset(), request.getLimit(),
+                    request.getUser().getUsername(), request.getUser().getFirstName(),
+                    request.getUser().getLastName(),
+                    request.getUser().getEmail(),
+                    request.getUser().getId());
+            List<org.apache.custos.iam.service.UserRepresentation> users = new ArrayList<>();
+            representation.stream().forEach(r -> {
+                boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                        r.getUsername(), request.getAccessToken());
+
+
+                if (status) {
+                    users.add(this.getUser(r, request.getClientId()));
+                }
+            });
+
+
+            FindUsersResponse response = FindUsersResponse.newBuilder().addAllUsers(users).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during getUsers" + ex;
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void resetPassword(ResetUserPassword request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        String userId = request.getUsername() + "@" + request.getTenantId();
+        try {
+            LOGGER.debug("Request received to resetPassword for " + request.getUsername());
+
+            boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                    request.getUsername(), request.getAccessToken());
+
+
+            if (!status) {
+                statusUpdater.updateStatus(IAMOperations.RESET_PASSWORD.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(), userId);
+                String msg = "User not valid ";
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            boolean isChanged = keycloakClient.resetUserPassword(request.getAccessToken(),
+                    String.valueOf(request.getTenantId()),
+                    request.getUsername(),
+                    request.getPassword());
+
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus.
+                    newBuilder().setStatus(isChanged).build();
+
+
+            statusUpdater.updateStatus(IAMOperations.RESET_PASSWORD.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), userId);
+
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during resetPassword" + ex;
+            LOGGER.error(msg, ex);
+
+            statusUpdater.updateStatus(IAMOperations.RESET_PASSWORD.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), userId);
+
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void updateUserProfile(UpdateUserProfileRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        String userId = request.getUser().getUsername() + "@" + request.getTenantId();
+
+        try {
+            LOGGER.debug("Request received to updateUserProfile for " + request.getUser().getUsername());
+
+            boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(), request.getAccessToken());
+
+
+            if (!status) {
+                statusUpdater.updateStatus(IAMOperations.UPDATE_USER_PROFILE.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(), userId);
+                String msg = "User not valid ";
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            keycloakClient.updateUserRepresentation(request.getAccessToken(),
+                    String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(),
+                    request.getUser().getFirstName(),
+                    request.getUser().getLastName(),
+                    request.getUser().getEmail());
+
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus.
+                    newBuilder().setStatus(true).build();
+
+
+            statusUpdater.updateStatus(IAMOperations.UPDATE_USER_PROFILE.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), userId);
+
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during updateUserProfile" + ex;
+            LOGGER.error(msg, ex);
+
+            statusUpdater.updateStatus(IAMOperations.UPDATE_USER_PROFILE.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), userId);
+
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteUser(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+
+        try {
+            LOGGER.debug("Request received to deleteUser for " + request.getTenantId());
+
+            boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(), request.getAccessToken());
+
+
+            if (!status) {
+                statusUpdater.updateStatus(IAMOperations.DELETE_USER.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(), request.getPerformedBy());
+                String msg = "User not valid ";
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            boolean isUpdated = keycloakClient.deleteUser(request.getAccessToken(),
+                    String.valueOf(request.getTenantId()), request.getUser().getUsername());
+
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus.
+                    newBuilder().setStatus(isUpdated).build();
+
+            statusUpdater.updateStatus(IAMOperations.DELETE_USER.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred during deleteUser" + ex;
+            LOGGER.error(msg, ex);
+
+            statusUpdater.updateStatus(IAMOperations.DELETE_USER.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+
+            if (ex.getMessage().contains("Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void deleteRolesFromUser(DeleteUserRolesRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+
+        try {
+            LOGGER.debug("Request received to deleteRoleFromUser for " + request.getTenantId());
+
+            boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                    request.getUsername(), request.getAccessToken());
+
+
+            if (!status) {
+                statusUpdater.updateStatus(IAMOperations.DELETE_ROLE_FROM_USER.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(), request.getPerformedBy());
+                String msg = "User not valid ";
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            if (!request.getRolesList().isEmpty()) {
+
+                keycloakClient.removeRoleFromUser(request.getAccessToken(),
+                        String.valueOf(request.getTenantId()), request.getUsername(),
+                        request.getRolesList(), request.getClientId(), false);
+            }
+
+            if (!request.getClientRolesList().isEmpty()) {
+                keycloakClient.removeRoleFromUser(request.getAccessToken(),
+                        String.valueOf(request.getTenantId()), request.getUsername(),
+                        request.getClientRolesList(), request.getClientId(), true);
+
+            }
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus.
+                    newBuilder().setStatus(true).build();
+
+
+            statusUpdater.updateStatus(IAMOperations.DELETE_ROLE_FROM_USER.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred during deleteRoleFromUser" + ex;
+            LOGGER.error(msg, ex);
+
+            statusUpdater.updateStatus(IAMOperations.DELETE_ROLE_FROM_USER.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+
+            if (ex.getMessage().contains("Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void getOperationMetadata(GetOperationsMetadataRequest request, StreamObserver<GetOperationsMetadataResponse> responseObserver) {
+        try {
+            LOGGER.debug("Calling getOperationMetadata API for traceId " + request.getTraceId());
+
+            List<OperationMetadata> metadata = new ArrayList<>();
+            List<StatusEntity> entities = statusUpdater.getOperationStatus(request.getTraceId());
+            if (entities == null || entities.size() > 0) {
+
+                for (StatusEntity statusEntity : entities) {
+                    OperationMetadata data = convertFromEntity(statusEntity);
+                    metadata.add(data);
+                }
+            }
+
+            GetOperationsMetadataResponse response = GetOperationsMetadataResponse
+                    .newBuilder()
+                    .addAllMetadata(metadata)
+                    .build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " operation failed for " + request.getTraceId();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void configureFederatedIDP(ConfigureFederateIDPRequest request, StreamObserver<FederateIDPResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to configureFederatedIDP for " + request.getTenantId());
+
+
+            keycloakClient.configureOIDCFederatedIDP(String.valueOf(request.getTenantId()), "CILogon", request.getScope(),
+                    new KeycloakClientSecret(request.getClientID(), request.getClientSec()), null);
+
+
+            FederateIDPResponse federateIDPResponse = FederateIDPResponse.newBuilder().setStatus(true).build();
+
+            statusUpdater.updateStatus(IAMOperations.CONFIGURE_IDP.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getRequesterEmail());
+
+            responseObserver.onNext(federateIDPResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Configure Federated IDP failed for " + request.getTenantId();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void registerAndEnableUsers(RegisterUsersRequest request, StreamObserver<RegisterUsersResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to registerMultipleUsers for " + request.getTenantId());
+
+            List<org.apache.custos.iam.service.UserRepresentation> userRepresentations = request.getUsersList();
+
+            List<org.apache.custos.iam.service.UserRepresentation> failedList = new ArrayList<>();
+
+
+            for (org.apache.custos.iam.service.UserRepresentation userRepresentation : userRepresentations) {
+
+                try {
+                    keycloakClient.createUser(String.valueOf(request.getTenantId()),
+                            userRepresentation.getUsername(),
+                            userRepresentation.getPassword(),
+                            userRepresentation.getFirstName(),
+                            userRepresentation.getLastName(),
+                            userRepresentation.getEmail(),
+                            userRepresentation.getTemporaryPassword(),
+                            request.getAccessToken());
+
+                    keycloakClient.enableUserAccount
+                            (String.valueOf(request.getTenantId()),
+                                    request.getAccessToken(), userRepresentation.getUsername().toLowerCase());
+                    List<String> userList = new ArrayList<>();
+                    userList.add(userRepresentation.getUsername());
+                    if (!userRepresentation.getRealmRolesList().isEmpty()) {
+                        keycloakClient.addRolesToUsers(request.getAccessToken(),
+                                String.valueOf(request.getTenantId()), userList, userRepresentation.getRealmRolesList(),
+                                request.getClientId(), false);
+                    }
+                    if (!userRepresentation.getClientRolesList().isEmpty()) {
+                        keycloakClient.addRolesToUsers(request.getAccessToken(),
+                                String.valueOf(request.getTenantId()), userList, userRepresentation.getClientRolesList(),
+                                request.getClientId(), true);
+                    }
+
+                    if (!userRepresentation.getAttributesList().isEmpty()) {
+
+                        Map<String, List<String>> map = new HashMap<>();
+                        for (UserAttribute attribute : userRepresentation.getAttributesList()) {
+
+                            if (attribute.getKey().equals(Constants.CUSTOS_REALM_AGENT)) {
+                                // Constants.CUSTOS_REALM_AGENT + " cannot be used as a valid attribute";
+                                continue;
+                            }
+                            map.put(attribute.getKey(), attribute.getValuesList());
+                        }
+
+                        keycloakClient.addUserAttributes(String.valueOf(request.getTenantId()),
+                                request.getAccessToken(), map, userList);
+
+                    }
+
+                } catch (UnauthorizedException ex) {
+                    LOGGER.error(" Error occurred while adding user " + userRepresentation.getUsername() +
+                            " to realm" + request.getTenantId());
+                    responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(ex.getMessage())
+                            .asRuntimeException());
+                    return;
+                } catch (Exception ex) {
+                    if (ex.getMessage().contains("Unauthorized")) {
+                        responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(ex.getMessage())
+                                .asRuntimeException());
+                        return;
+                    }
+                    LOGGER.error(" Error occurred while adding user " + userRepresentation.getUsername() +
+                            " to realm" + request.getTenantId());
+                    failedList.add(userRepresentation);
+                }
+            }
+
+            if (failedList.isEmpty()) {
+                statusUpdater.updateStatus(IAMOperations.REGISTER_ENABLE_USERS.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(),
+                        request.getPerformedBy());
+            }
+
+
+            RegisterUsersResponse response = RegisterUsersResponse.newBuilder()
+                    .setAllUseresRegistered(failedList.isEmpty())
+                    .addAllFailedUsers(failedList).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.REGISTER_ENABLE_USERS.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+            String msg = " Register  multiple users  failed for " + request.getTenantId();
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+
+        }
+    }
+
+
+    @Override
+    public void addRolesToUsers(AddUserRolesRequest request,
+                                StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addRolesToUsers for " + request.getTenantId());
+
+            List<String> validUserNames = new ArrayList<>();
+
+            for (String username : request.getUsernamesList()) {
+                boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                        username, request.getAccessToken());
+
+                if (status) {
+                    validUserNames.add(username);
+                }
+            }
+
+            keycloakClient.addRolesToUsers(request.getAccessToken(), String.valueOf(request.getTenantId()),
+                    validUserNames, request.getRolesList(), request.getClientId(), request.getClientLevel());
+
+            statusUpdater.updateStatus(IAMOperations.ADD_ROLES_TO_USERS.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            org.apache.custos.iam.service.OperationStatus status = org.apache.custos.iam.service.OperationStatus.
+                    newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.ADD_ROLES_TO_USERS.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            String msg = " Add  multiple users  failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void addRolesToTenant(AddRolesRequest request, StreamObserver<AllRoles> responseObserver) {
+        try {
+            LOGGER.debug("Request received to add roles to tenant for " + request.getTenantId());
+
+            List<RoleRepresentation> rolesRepresentations = request.getRolesList();
+
+            List<org.keycloak.representations.idm.RoleRepresentation> keycloakRolesList = new ArrayList<>();
+
+            for (RoleRepresentation roleRepresentation : rolesRepresentations) {
+                org.keycloak.representations.idm.RoleRepresentation role = new org.keycloak.representations.idm.RoleRepresentation();
+                role.setName(roleRepresentation.getName());
+                role.setDescription(roleRepresentation.getDescription());
+                role.setComposite(roleRepresentation.getComposite());
+                keycloakRolesList.add(role);
+            }
+
+            keycloakClient.addRoles(keycloakRolesList, String.valueOf(request.getTenantId()),
+                    request.getClientId(), request.getClientLevel());
+
+            statusUpdater.updateStatus(IAMOperations.ADD_ROLES_TO_TENANT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+
+            List<org.keycloak.representations.idm.RoleRepresentation> allKeycloakRoles = keycloakClient.
+                    getAllRoles(String.valueOf(request.getTenantId()), (request.getClientLevel()) ? request.getClientId() : null);
+            AllRoles.Builder builder = AllRoles.newBuilder();
+            if (allKeycloakRoles != null && !allKeycloakRoles.isEmpty()) {
+
+                List<RoleRepresentation> roleRepresentations = new ArrayList<>();
+                for (org.keycloak.representations.idm.RoleRepresentation role : allKeycloakRoles) {
+                    RoleRepresentation roleRepresentation = RoleRepresentation.
+                            newBuilder().setName(role.getName())
+                            .setComposite(role.isComposite())
+                            .build();
+                    if (role.getDescription() != null) {
+                        roleRepresentation = roleRepresentation.toBuilder().setDescription(role.getDescription()).build();
+                    }
+                    roleRepresentations.add(roleRepresentation);
+
+
+                }
+
+                builder.addAllRoles(roleRepresentations);
+                if (request.getClientLevel()) {
+                    builder.setScope("client_level");
+                } else {
+                    builder.setScope("realm_level");
+                }
+
+            }
+
+            responseObserver.onNext(builder.build());
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.ADD_ROLES_TO_TENANT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+            String msg = " Add roles   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getRolesOfTenant(GetRolesRequest request, StreamObserver<AllRoles> responseObserver) {
+        try {
+            LOGGER.debug("Request received to add roles to tenant for " + request.getTenantId());
+
+            List<org.keycloak.representations.idm.RoleRepresentation> allKeycloakRoles = keycloakClient.
+                    getAllRoles(String.valueOf(request.getTenantId()), (request.getClientLevel()) ? request.getClientId() : null);
+            AllRoles.Builder builder = AllRoles.newBuilder();
+            if (allKeycloakRoles != null && !allKeycloakRoles.isEmpty()) {
+
+                List<RoleRepresentation> roleRepresentations = new ArrayList<>();
+                for (org.keycloak.representations.idm.RoleRepresentation role : allKeycloakRoles) {
+                    RoleRepresentation roleRepresentation = RoleRepresentation.
+                            newBuilder().setName(role.getName())
+                            .setComposite(role.isComposite())
+                            .build();
+                    if (role.getDescription() != null) {
+                        roleRepresentation = roleRepresentation.toBuilder().setDescription(role.getDescription()).build();
+                    }
+                    roleRepresentations.add(roleRepresentation);
+
+                }
+
+                builder.addAllRoles(roleRepresentations);
+                if (request.getClientLevel()) {
+                    builder.setScope("client_level");
+                } else {
+                    builder.setScope("realm_level");
+                }
+            }
+
+            responseObserver.onNext(builder.build());
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Get roles   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addProtocolMapper(AddProtocolMapperRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to add protocol mapper " + request.getTenantId());
+
+            String mapperModel = "oidc-usermodel-attribute-mapper";
+            Map<String, String> configMap = new HashMap<>();
+            if (request.getMapperType().equals(MapperTypes.USER_ATTRIBUTE)) {
+                mapperModel = "oidc-usermodel-attribute-mapper";
+                configMap.put("user.attribute", request.getAttributeName());
+            } else if (request.getMapperType().equals(MapperTypes.USER_REALM_ROLE)) {
+                mapperModel = "oidc-usermodel-realm-role-mapper";
+            } else if (request.getMapperType().equals(MapperTypes.USER_CLIENT_ROLE)) {
+                mapperModel = "oidc-usermodel-client-role-mapper";
+                configMap.put("usermodel.clientRoleMapping.clientId", request.getClientId());
+            } else {
+                responseObserver.onError(io.grpc.Status.UNIMPLEMENTED.
+                        withDescription("Mapping type not supported").asRuntimeException());
+                return;
+            }
+
+            ProtocolMapperRepresentation protocolMapperRepresentation = new ProtocolMapperRepresentation();
+            protocolMapperRepresentation.setName(request.getName());
+            protocolMapperRepresentation.setProtocol("openid-connect");
+            protocolMapperRepresentation.setProtocolMapper(mapperModel);
+
+            configMap.put("user.session.note", request.getClaimName());
+            configMap.put("id.token.claim", String.valueOf(request.getAddToIdToken()));
+            configMap.put("access.token.claim", String.valueOf(request.getAddToAccessToken()));
+            configMap.put("claim.name", request.getClaimName());
+            switch (request.getClaimType()) {
+                case JSON:
+                    configMap.put("jsonType.label", "JSON");
+                    break;
+                case LONG:
+                    configMap.put("jsonType.label", "long");
+                    break;
+                case STRING:
+                    configMap.put("jsonType.label", "String");
+                    break;
+                case BOOLEAN:
+                    configMap.put("jsonType.label", "boolean");
+                    break;
+                case INTEGER:
+                    configMap.put("jsonType.label", "int");
+                    break;
+                default: {
+                    responseObserver.onError(io.grpc.Status.INVALID_ARGUMENT.
+                            withDescription("Unknown claim type").asRuntimeException());
+                    return;
+                }
+            }
+
+            configMap.put("aggregate.attrs", String.valueOf(request.getAggregateAttributeValues()));
+            configMap.put("userinfo.token.claim", String.valueOf(request.getAddToUserInfo()));
+            configMap.put("multivalued", String.valueOf(request.getMultiValued()));
+
+
+            protocolMapperRepresentation.setConfig(configMap);
+
+            keycloakClient.addProtocolMapper(protocolMapperRepresentation, String.valueOf(request.getTenantId()),
+                    request.getClientId());
+
+            statusUpdater.updateStatus(IAMOperations.ADD_PROTOCOL_MAPPER.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+
+            org.apache.custos.iam.service.OperationStatus status =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.ADD_PROTOCOL_MAPPER.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    String.valueOf(request.getTenantId()));
+            String msg = " Add protocol mapper   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addUserAttributes(AddUserAttributesRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addUserAttributes " + request.getTenantId());
+
+            List<UserAttribute> attributes = request.getAttributesList();
+
+            List<String> validUserNames = new ArrayList<>();
+
+            for (String username : request.getUsersList()) {
+                boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                        username, request.getAccessToken());
+
+                if (status) {
+                    validUserNames.add(username);
+                }
+            }
+
+            Map<String, List<String>> attributeMap = new HashMap<>();
+            for (UserAttribute attribute : attributes) {
+                if (attribute.getKey().equals(Constants.CUSTOS_REALM_AGENT)) {
+                    String msg = Constants.CUSTOS_REALM_AGENT + " cannot be used as a valid attribute";
+                    LOGGER.error(msg);
+                    responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+                }
+
+                attributeMap.put(attribute.getKey(), attribute.getValuesList());
+            }
+
+            keycloakClient.addUserAttributes(String.valueOf(request.getTenantId()), request.getAccessToken(), attributeMap, validUserNames);
+
+            statusUpdater.updateStatus(IAMOperations.ADD_USER_ATTRIBUTE.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            org.apache.custos.iam.service.OperationStatus status =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.ADD_USER_ATTRIBUTE.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            String msg = " Add attributes   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void deleteUserAttributes(DeleteUserAttributeRequest request,
+                                     StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to delete user attributes " + request.getTenantId());
+
+            List<String> validUserNames = new ArrayList<>();
+
+            for (String username : request.getUsersList()) {
+                boolean status = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                        username, request.getAccessToken());
+
+                if (status) {
+                    validUserNames.add(username);
+                }
+            }
+
+
+            List<UserAttribute> attributes = request.getAttributesList();
+
+            Map<String, List<String>> attributeMap = new HashMap<>();
+            for (UserAttribute attribute : attributes) {
+                attributeMap.put(attribute.getKey(), attribute.getValuesList());
+
+            }
+
+            keycloakClient.deleteUserAttributes(String.valueOf(request.getTenantId()), request.getAccessToken(), attributeMap, validUserNames);
+
+            statusUpdater.updateStatus(IAMOperations.DELETE_USER_ATTRIBUTES.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            org.apache.custos.iam.service.OperationStatus status =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.DELETE_USER_ATTRIBUTES.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            String msg = " Add attributes   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void configureEventPersistence(EventPersistenceRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to configureEventPersistence " + request.getTenantId());
+
+            keycloakClient.configureEventPersistence(
+                    String.valueOf(request.getTenantId()),
+                    request.getEvent(),
+                    request.getPersistenceTime(),
+                    request.getEnable(),
+                    request.getAdminEvent()
+            );
+            org.apache.custos.iam.service.OperationStatus status =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.CONFIGURE_PERSISTANCE.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            String msg = " Configure Event Persistence   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void createGroups(GroupsRequest request, StreamObserver<GroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createGroup " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+            String accessToken = request.getAccessToken();
+
+            List<org.keycloak.representations.idm.GroupRepresentation> groupRepresentations =
+                    transformToKeycloakGroups(request.getClientId(), request.getGroupsList());
+
+            List<org.keycloak.representations.idm.GroupRepresentation> representations =
+                    keycloakClient.createGroups(String.valueOf(tenantId), request.getClientId(), request.getClientSec(), groupRepresentations);
+
+            List<GroupRepresentation> groups = transformKeycloakGroupsToGroups(request.getClientId(), representations);
+
+            statusUpdater.updateStatus(IAMOperations.CREATE_GROUP.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            GroupsResponse response = GroupsResponse.newBuilder().addAllGroups(groups).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.CREATE_GROUP.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            String msg = " Create Group   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void updateGroup(GroupRequest request, StreamObserver<GroupRepresentation> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateGroup " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+            String accessToken = request.getAccessToken();
+
+            List<GroupRepresentation> representations = new ArrayList<>();
+            representations.add(request.getGroup());
+            List<org.keycloak.representations.idm.GroupRepresentation> groupRepresentations =
+                    transformToKeycloakGroups(request.getClientId(), representations);
+
+            org.keycloak.representations.idm.GroupRepresentation groupRepresentation =
+                    keycloakClient.updateGroup(String.valueOf(tenantId), request.getClientId(), request.getClientSec(), groupRepresentations.get(0));
+
+            GroupRepresentation group = transformKeycloakGroupToGroup(request.getClientId(), groupRepresentation, null);
+
+            statusUpdater.updateStatus(IAMOperations.UPDATE_GROUP.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            responseObserver.onNext(group);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.UPDATE_GROUP.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            String msg = " Update Group   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void deleteGroup(GroupRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteGroup " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+            String accessToken = request.getAccessToken();
+
+            keycloakClient.deleteGroup(String.valueOf(tenantId)
+                    , request.getClientId(), request.getClientSec(), request.getGroup().getId());
+
+
+            statusUpdater.updateStatus(IAMOperations.DELETE_GROUP.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            org.apache.custos.iam.service.OperationStatus operationStatus = org.apache.custos.iam.service.OperationStatus
+                    .newBuilder().setStatus(true).build();
+
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.DELETE_GROUP.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            String msg = " Delete Group   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void findGroup(GroupRequest request, StreamObserver<GroupRepresentation> responseObserver) {
+        try {
+            LOGGER.debug("Request received to findGroup " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+            String accessToken = request.getAccessToken();
+
+
+            org.keycloak.representations.idm.GroupRepresentation groupRepresentation =
+                    keycloakClient.findGroup(String.valueOf(tenantId)
+                            , accessToken, request.getGroup().getId(), request.getGroup().getName());
+
+            if (groupRepresentation != null) {
+                GroupRepresentation group = transformKeycloakGroupToGroup(request.getClientId(), groupRepresentation, null);
+                responseObserver.onNext(group);
+                responseObserver.onCompleted();
+            } else {
+                responseObserver.onNext(null);
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception ex) {
+            String msg = " find Group   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void getAllGroups(GroupRequest request, StreamObserver<GroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllGroups " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+            String accessToken = request.getAccessToken();
+
+
+            List<org.keycloak.representations.idm.GroupRepresentation> groupRepresentation =
+                    keycloakClient.getAllGroups(String.valueOf(tenantId)
+                            , accessToken);
+
+            List<GroupRepresentation> groups = transformKeycloakGroupsToGroups(request.getClientId(), groupRepresentation);
+
+
+            if (groups != null && !groups.isEmpty()) {
+                GroupsResponse response = GroupsResponse.newBuilder().addAllGroups(groups).build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+
+            } else {
+                GroupsResponse response = GroupsResponse.newBuilder().build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception ex) {
+            String msg = " Get Groups   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void addUserToGroup(UserGroupMappingRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllGroups " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+            String accessToken = request.getAccessToken();
+
+
+            boolean status = keycloakClient.
+                    addUserToGroup(String.valueOf(tenantId), request.getUsername(), request.getGroupId(), accessToken);
+
+            if (status) {
+                statusUpdater.updateStatus(IAMOperations.ADD_USER_TO_GROUP.name(),
+                        OperationStatus.SUCCESS,
+                        request.getTenantId(),
+                        request.getPerformedBy());
+            } else {
+                statusUpdater.updateStatus(IAMOperations.ADD_USER_TO_GROUP.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(),
+                        request.getPerformedBy());
+            }
+
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus
+                    .newBuilder()
+                    .setStatus(status)
+                    .build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.ADD_USER_TO_GROUP.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            String msg = "  Groups   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+
+
+    }
+
+    @Override
+    public void removeUserFromGroup(UserGroupMappingRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllGroups " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+            String accessToken = request.getAccessToken();
+
+
+            boolean status = keycloakClient.
+                    removeUserFromGroup(String.valueOf(tenantId), request.getUsername(), request.getGroupId(), accessToken);
+
+
+            if (status) {
+                statusUpdater.updateStatus(IAMOperations.REMOVE_USER_FROM_GROUP.name(),
+                        OperationStatus.SUCCESS,
+                        request.getTenantId(),
+                        request.getPerformedBy());
+            } else {
+                statusUpdater.updateStatus(IAMOperations.REMOVE_USER_FROM_GROUP.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(),
+                        request.getPerformedBy());
+            }
+
+
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus
+                    .newBuilder()
+                    .setStatus(status)
+                    .build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+
+            statusUpdater.updateStatus(IAMOperations.REMOVE_USER_FROM_GROUP.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+
+            String msg = "  Remove user from Group   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+
+
+    }
+
+
+    @Override
+    public void createAgentClient(AgentClientMetadata request, StreamObserver<SetUpTenantResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to configureAgentClient " + request.getTenantId());
+
+            KeycloakClientSecret secret = keycloakClient.configureClient(
+                    String.valueOf(request.getTenantId()),
+                    request.getClientName(),
+                    request.getTenantURL(),
+                    request.getRedirectURIsList());
+
+            if (secret != null) {
+
+                statusUpdater.updateStatus(IAMOperations.CONFIGURE_AGENT_CLIENT.name(),
+                        OperationStatus.SUCCESS,
+                        request.getTenantId(),
+                        request.getPerformedBy());
+
+                SetUpTenantResponse response = SetUpTenantResponse.newBuilder()
+                        .setClientId(secret.getClientId())
+                        .setClientSecret(secret.getClientSecret())
+                        .build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            } else {
+                String msg = " Configure agent client  failed for " + request.getTenantId();
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        } catch (Exception ex) {
+            statusUpdater.updateStatus(IAMOperations.CONFIGURE_AGENT_CLIENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(),
+                    request.getPerformedBy());
+            String msg = " Configure agent client  failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void configureAgentClient(AgentClientMetadata request,
+                                     StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to configureAgentClient " + request.getTenantId());
+
+            boolean status = keycloakClient.configureAgentClient(String.valueOf(request.getTenantId()), request.getClientName(),
+                    request.getAccessTokenLifeTime());
+
+            org.apache.custos.iam.service.OperationStatus operationStatus =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Register and configureAgentClient user   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.REGISTER_AGENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void registerAndEnableAgent(RegisterUserRequest request, StreamObserver<RegisterUserResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to registerAndEnableAgent " + request.getTenantId());
+
+            boolean status = keycloakClient.createUser(String.valueOf(request.getTenantId()),
+                    request.getUser().getId(),
+                    request.getUser().getPassword(),
+                    null,
+                    null,
+                    null,
+                    false,
+                    request.getAccessToken());
+
+            if (status) {
+
+                List<String> userList = new ArrayList<>();
+                userList.add(request.getUser().getId());
+                if (!request.getUser().getRealmRolesList().isEmpty()) {
+                    keycloakClient.addRolesToUsers(request.getAccessToken(),
+                            String.valueOf(request.getTenantId()), userList, request.getUser().getRealmRolesList(),
+                            request.getClientId(), false);
+                }
+                if (!request.getUser().getClientRolesList().isEmpty()) {
+                    keycloakClient.addRolesToUsers(request.getAccessToken(),
+                            String.valueOf(request.getTenantId()), userList, request.getUser().getClientRolesList(),
+                            request.getClientId(), true);
+                }
+
+                if (!request.getUser().getAttributesList().isEmpty()) {
+
+                    Map<String, List<String>> map = new HashMap<>();
+                    for (UserAttribute attribute : request.getUser().getAttributesList()) {
+
+                        map.put(attribute.getKey(), attribute.getValuesList());
+                    }
+
+                    keycloakClient.addUserAttributes(String.valueOf(request.getTenantId()),
+                            request.getAccessToken(), map, userList);
+
+                }
+
+                status = keycloakClient.enableUserAccount(String.valueOf(request.getTenantId()),
+                        request.getAccessToken(), request.getUser().getId());
+                statusUpdater.updateStatus(IAMOperations.REGISTER_AGENT.name(),
+                        OperationStatus.SUCCESS,
+                        request.getTenantId(), request.getPerformedBy());
+
+                RegisterUserResponse response = RegisterUserResponse.newBuilder().setIsRegistered(status).build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+
+            } else {
+                String msg = " Register and enable user   failed for  user " + request.getUser().getId() + "of tenant"
+                        + request.getTenantId();
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = " Register and enable user   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.REGISTER_AGENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void deleteAgent(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteAgent " + request.getTenantId());
+
+            boolean status = keycloakClient.deleteUser(request.getAccessToken(),
+                    String.valueOf(request.getTenantId()), request.getUser().getId());
+
+            statusUpdater.updateStatus(IAMOperations.DELETE_AGENT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+            org.apache.custos.iam.service.OperationStatus operationStatus =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Delete agent  failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.DELETE_AGENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void disableAgent(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to disableAgent " + request.getTenantId());
+            boolean status = keycloakClient.disableUserAccount(
+                    String.valueOf(request.getTenantId()), request.getAccessToken(), request.getUser().getId());
+
+            statusUpdater.updateStatus(IAMOperations.DISABLE_AGENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+
+            org.apache.custos.iam.service.OperationStatus operationStatus =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Disable agent   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.DELETE_USER.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void isAgentNameAvailable(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to isAgentNameAvailable " + request.getTenantId());
+            boolean status = keycloakClient.isUsernameAvailable(
+                    String.valueOf(request.getTenantId()), request.getUser().getId(), request.getAccessToken());
+
+            org.apache.custos.iam.service.OperationStatus operationStatus =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Is agent name available   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void addAgentAttributes(AddUserAttributesRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addAgentAttributes " + request.getTenantId());
+
+            List<UserAttribute> attributes = request.getAttributesList();
+
+            Map<String, List<String>> attributeMap = new HashMap<>();
+
+            for (UserAttribute attribute : attributes) {
+                attributeMap.put(attribute.getKey(), attribute.getValuesList());
+            }
+
+            boolean status = keycloakClient.addUserAttributes(String.valueOf(request.getTenantId()), request.getAccessToken(),
+                    attributeMap, request.getAgentsList());
+
+            statusUpdater.updateStatus(IAMOperations.ADD_AGENT_ATTRIBUTES.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+            org.apache.custos.iam.service.OperationStatus response =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = " Add agent attributes   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.ADD_AGENT_ATTRIBUTES.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void deleteAgentAttributes(DeleteUserAttributeRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteAgentAttributes " + request.getTenantId());
+            List<UserAttribute> attributes = request.getAttributesList();
+
+            Map<String, List<String>> attributeMap = new HashMap<>();
+            for (UserAttribute attribute : attributes) {
+                attributeMap.put(attribute.getKey(), attribute.getValuesList());
+            }
+
+            boolean status = keycloakClient.deleteUserAttributes
+                    (String.valueOf(request.getTenantId()), request.getAccessToken(), attributeMap, request.getAgentsList());
+            statusUpdater.updateStatus(IAMOperations.DELETE_AGENT_ATTRIBUTES.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+
+            org.apache.custos.iam.service.OperationStatus response =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Delete agent attributes   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.DELETE_AGENT_ATTRIBUTES.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void addRolesToAgent(AddUserRolesRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addRolesToAgent " + request.getTenantId());
+            boolean status = keycloakClient.addRolesToUsers(request.getAccessToken(), String.valueOf(request.getTenantId()),
+                    request.getAgentsList(), request.getRolesList(), request.getClientId(), request.getClientLevel());
+            statusUpdater.updateStatus(IAMOperations.ADD_ROLE_TO_AGENT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus.
+                    newBuilder().setStatus(status).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Add roles to agent   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.ADD_ROLE_TO_AGENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void deleteAgentRoles(DeleteUserRolesRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteRolesFromAgent " + request.getTenantId());
+
+            if (!request.getRolesList().isEmpty()) {
+
+                keycloakClient.removeRoleFromUser(request.getAccessToken(),
+                        String.valueOf(request.getTenantId()), request.getId(),
+                        request.getRolesList(), request.getClientId(), false);
+            }
+
+            if (!request.getClientRolesList().isEmpty()) {
+                keycloakClient.removeRoleFromUser(request.getAccessToken(),
+                        String.valueOf(request.getTenantId()), request.getId(),
+                        request.getClientRolesList(), request.getClientId(), true);
+
+            }
+            statusUpdater.updateStatus(IAMOperations.DELETE_ROLE_FROM_AGENT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+            org.apache.custos.iam.service.OperationStatus response = org.apache.custos.iam.service.OperationStatus.
+                    newBuilder().setStatus(true).build();
+
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Delete roles from agent   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.DELETE_ROLE_FROM_AGENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void getAgent(UserSearchRequest request, StreamObserver<Agent> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAgent " + request.getTenantId());
+
+            UserRepresentation representation = keycloakClient.getUser(String.valueOf(request.getTenantId()), request.getAccessToken(),
+                    request.getUser().getId());
+
+            if (representation != null) {
+                if (representation.getAttributes() == null || representation.getAttributes().isEmpty() ||
+                        representation.getAttributes().get(Constants.CUSTOS_REALM_AGENT).get(0) == null ||
+                        !representation.getAttributes().get(Constants.CUSTOS_REALM_AGENT).get(0).equals("true")) {
+                    responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription("Agent not found ").asRuntimeException());
+                    return;
+                } else {
+
+                    Agent agent = getAgent(representation);
+                    responseObserver.onNext(agent);
+                    responseObserver.onCompleted();
+                }
+            }
+            {
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription("Agent not found ").asRuntimeException());
+                return;
+            }
+
+
+        } catch (Exception ex) {
+            String msg = " Delete roles from agent   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.DELETE_ROLE_FROM_AGENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void enableAgent(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to enableAgent " + request.getTenantId());
+            boolean status = keycloakClient.enableUserAccount(
+                    String.valueOf(request.getTenantId()), request.getAccessToken(), request.getUser().getId());
+
+            statusUpdater.updateStatus(IAMOperations.ENABLE_AGENT.name(),
+                    OperationStatus.FAILED,
+                    request.getTenantId(), request.getPerformedBy());
+
+            org.apache.custos.iam.service.OperationStatus operationStatus =
+                    org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = " Enable agent   failed for " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.ENABLE_AGENT.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void grantAdminPrivilege(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to grantAdminPrivilege " + request.getTenantId());
+
+            boolean validationStatus = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(), request.getAccessToken());
+
+            if (validationStatus) {
+
+                boolean status = keycloakClient.grantAdminPrivilege(String.valueOf(request.getTenantId()), request.getUser().getUsername());
+
+                statusUpdater.updateStatus(IAMOperations.GRANT_ADMIN_PRIVILEGE.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(), request.getPerformedBy());
+
+                org.apache.custos.iam.service.OperationStatus operationStatus =
+                        org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+
+                responseObserver.onNext(operationStatus);
+                responseObserver.onCompleted();
+            } else {
+                String msg = " Not a valid user";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = " Grant admin privilege " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.GRANT_ADMIN_PRIVILEGE.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void removeAdminPrivilege(UserSearchRequest request, StreamObserver<org.apache.custos.iam.service.OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to removeAdminPrivilege " + request.getTenantId());
+
+            boolean validationStatus = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                    request.getUser().getUsername(), request.getAccessToken());
+
+            if (validationStatus) {
+
+                boolean status = keycloakClient.removeAdminPrivilege(String.valueOf(request.getTenantId()), request.getUser().getUsername());
+
+                statusUpdater.updateStatus(IAMOperations.REMOVE_ADMIN_PRIVILEGE.name(),
+                        OperationStatus.FAILED,
+                        request.getTenantId(), request.getPerformedBy());
+
+                org.apache.custos.iam.service.OperationStatus operationStatus =
+                        org.apache.custos.iam.service.OperationStatus.newBuilder().setStatus(status).build();
+
+                responseObserver.onNext(operationStatus);
+                responseObserver.onCompleted();
+            } else {
+                String msg = " Not a valid user";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = " Remove admin privilege " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            statusUpdater.updateStatus(IAMOperations.REMOVE_ADMIN_PRIVILEGE.name(),
+                    OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void getAllResources(GetAllResources request, StreamObserver<GetAllResourcesResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllResources for tenant " + request.getTenantId());
+
+            List<UserRepresentation> representations = keycloakClient.getAllUsers(String.valueOf(request.getTenantId()));
+            GetAllResourcesResponse resourcesResponse = GetAllResourcesResponse.newBuilder().build();
+            if (!representations.isEmpty()) {
+                if (request.getResourceType().name().equals(ResourceTypes.USER.name())) {
+                    List<org.apache.custos.iam.service.UserRepresentation> users = new ArrayList<>();
+                    for (UserRepresentation userRepresentation : representations) {
+
+                        boolean validationStatus = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                                userRepresentation.getUsername());
+                        if (validationStatus) {
+                            users.add(getUser(userRepresentation, request.getClientId()));
+
+                        }
+
+                    }
+
+                    resourcesResponse = resourcesResponse.toBuilder().addAllUsers(users).build();
+                    responseObserver.onNext(resourcesResponse);
+                    responseObserver.onCompleted();
+
+                } else {
+                    List<Agent> agents = new ArrayList<>();
+                    for (UserRepresentation userRepresentation : representations) {
+                        boolean validationStatus = keycloakClient.isValidEndUser(String.valueOf(request.getTenantId()),
+                                userRepresentation.getUsername());
+                        if (!validationStatus) {
+                            agents.add(getAgent(userRepresentation));
+                        }
+                    }
+
+                    resourcesResponse = resourcesResponse.toBuilder().addAllAgents(agents).build();
+                    responseObserver.onNext(resourcesResponse);
+                    responseObserver.onCompleted();
+
+                }
+
+            } else {
+                String msg = " Empty resources";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = " Get all resources failed";
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("HTTP 401 Unauthorized")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    private OperationMetadata convertFromEntity(StatusEntity entity) {
+        return OperationMetadata.newBuilder()
+                .setEvent(entity.getEvent())
+                .setStatus(entity.getState())
+                .setPerformedBy(entity.getPerformedBy())
+                .setTimeStamp(entity.getTime().toString()).build();
+    }
+
+
+    private Agent getAgent(UserRepresentation representation) {
+
+        Agent.Builder builder = Agent.newBuilder().setId(representation.getUsername())
+                .setIsEnabled(representation.isEnabled())
+                .setCreationTime(representation.getCreatedTimestamp());
+
+        for (String key : representation.getAttributes().keySet()) {
+            UserAttribute attribute = UserAttribute.newBuilder().setKey(key)
+                    .addAllValues(representation.getAttributes().get(key))
+                    .build();
+            builder.addAttributes(attribute);
+        }
+
+        if (representation.getRealmRoles() != null && !representation.getRealmRoles().isEmpty()) {
+            builder.addAllRealmRoles(representation.getRealmRoles());
+        }
+
+        if (representation.getClientRoles() != null && !representation.getClientRoles().isEmpty() &&
+                representation.getClientRoles().get(Constants.AGENT_CLIENT) != null &&
+                !representation.getClientRoles().get(Constants.AGENT_CLIENT).isEmpty()) {
+            builder.addAllClientRoles(representation.getClientRoles().get(Constants.AGENT_CLIENT));
+        }
+
+        return builder.build();
+    }
+
+
+    private org.apache.custos.iam.service.UserRepresentation getUser(UserRepresentation representation, String clientId) {
+        String state = Status.PENDING_CONFIRMATION;
+        if (representation.isEnabled()) {
+            state = Status.ACTIVE;
+        } else if (representation.isEmailVerified()) {
+            state = Status.CONFIRMED;
+        }
+
+        Map<String, List<String>> attributes = representation.getAttributes();
+
+        List<UserAttribute> attributeList = new ArrayList<>();
+
+        if (attributes != null && !attributes.isEmpty()) {
+            for (String key : attributes.keySet()) {
+                UserAttribute attribute = UserAttribute.
+                        newBuilder()
+                        .setKey(key)
+                        .addAllValues(attributes.get(key)).build();
+                attributeList.add(attribute);
+            }
+        }
+
+        org.apache.custos.iam.service.UserRepresentation.Builder builder = org.apache.custos.iam.service.UserRepresentation.newBuilder()
+                .setUsername(representation.getUsername())
+                .setFirstName(representation.getFirstName())
+                .setLastName(representation.getLastName())
+                .setState(state)
+                .setCreationTime(representation.getCreatedTimestamp())
+                .setEmail(representation.getEmail());
+
+
+        if (representation.getAttributes() != null && !representation.getAttributes().isEmpty()) {
+            builder.addAllAttributes(attributeList);
+        }
+
+
+        if (representation.getRealmRoles() != null && !representation.getRealmRoles().isEmpty()) {
+            builder.addAllRealmRoles(representation.getRealmRoles());
+        }
+
+        if (representation.getClientRoles() != null && representation.getClientRoles().get(clientId) != null &&
+                !representation.getClientRoles().get(clientId).isEmpty()) {
+            builder.addAllClientRoles(representation.getClientRoles().get(clientId));
+        }
+
+        return builder.build();
+
+    }
+
+    private List<org.keycloak.representations.idm.GroupRepresentation> transformToKeycloakGroups(String clientId, List<GroupRepresentation> groupRepresentations) {
+        List<org.keycloak.representations.idm.GroupRepresentation> groupsList = new ArrayList<>();
+        for (GroupRepresentation groupRepresentation : groupRepresentations) {
+            groupsList.add(transformSingleGroupToKeycloakGroup(clientId, groupRepresentation, null));
+        }
+        return groupsList;
+    }
+
+    private org.keycloak.representations.idm.GroupRepresentation
+    transformSingleGroupToKeycloakGroup(String clientId, GroupRepresentation groupRepresentation,
+                                        org.keycloak.representations.idm.GroupRepresentation parentGroup) {
+        String name = groupRepresentation.getName();
+        String id = groupRepresentation.getId();
+
+        if (groupRepresentation.getOwnerId() != null && !groupRepresentation.getOwnerId().equals("")) {
+
+            groupRepresentation = groupRepresentation.toBuilder().addAttributes(UserAttribute.newBuilder()
+                    .setKey(Constants.OWNER_ID).addValues(groupRepresentation.getOwnerId()).build()).build();
+        }
+
+        if (groupRepresentation.getDescription() != null && !groupRepresentation.getDescription().equals("")) {
+
+            groupRepresentation = groupRepresentation.toBuilder().addAttributes(UserAttribute.newBuilder()
+                    .setKey(Constants.DESCRIPTION).addValues(groupRepresentation.getDescription()).build()).build();
+        }
+
+
+        List<UserAttribute> attributeList = groupRepresentation.getAttributesList();
+        List<String> realmRoles = groupRepresentation.getRealmRolesList();
+        List<String> clientRoles = groupRepresentation.getClientRolesList();
+
+        org.keycloak.representations.idm.GroupRepresentation keycloakGroup =
+                new org.keycloak.representations.idm.GroupRepresentation();
+
+        keycloakGroup.setName(name);
+
+        if (id != null && !id.trim().equals("")) {
+            keycloakGroup.setId(id);
+        }
+
+
+        Map<String, List<String>> map = new HashMap<>();
+        if (attributeList != null && !attributeList.isEmpty()) {
+            for (UserAttribute attribute : attributeList) {
+                map.put(attribute.getKey(), attribute.getValuesList());
+            }
+            keycloakGroup.setAttributes(map);
+        }
+
+
+        if (realmRoles != null && !realmRoles.isEmpty()) {
+            keycloakGroup.setRealmRoles(realmRoles);
+
+        }
+
+        Map<String, List<String>> clientMap = new HashMap<>();
+        if (clientRoles != null && !clientRoles.isEmpty()) {
+            clientMap.put(clientId, clientRoles);
+            keycloakGroup.setClientRoles(clientMap);
+        }
+
+        if (groupRepresentation.getSubGroupsList() != null && !groupRepresentation.getSubGroupsList().isEmpty()) {
+            for (GroupRepresentation representation : groupRepresentation.getSubGroupsList()) {
+                transformSingleGroupToKeycloakGroup(clientId, representation, keycloakGroup);
+            }
+
+        }
+
+        if (parentGroup != null) {
+            List<org.keycloak.representations.idm.GroupRepresentation> groupRepList = parentGroup.getSubGroups();
+            if (groupRepList == null) {
+                groupRepList = new ArrayList<>();
+            }
+            String path = parentGroup.getPath() + "/" + keycloakGroup.getName();
+            keycloakGroup.setPath(path);
+            groupRepList.add(keycloakGroup);
+            parentGroup.setSubGroups(groupRepList);
+            return parentGroup;
+        }
+
+        String path = "/" + keycloakGroup.getName();
+        keycloakGroup.setPath(path);
+
+        return keycloakGroup;
+    }
+
+    private List<GroupRepresentation> transformKeycloakGroupsToGroups
+            (String clientId, List<org.keycloak.representations.idm.GroupRepresentation> groupRepresentations) {
+        List<GroupRepresentation> groupsList = new ArrayList<>();
+        for (org.keycloak.representations.idm.GroupRepresentation groupRepresentation : groupRepresentations) {
+            groupsList.add(transformKeycloakGroupToGroup(clientId, groupRepresentation, null));
+        }
+        return groupsList;
+    }
+
+    private GroupRepresentation transformKeycloakGroupToGroup(String clientId,
+                                                              org.keycloak.representations.idm.GroupRepresentation group,
+                                                              GroupRepresentation parent) {
+        String name = group.getName();
+        String id = group.getId();
+        List<String> realmRoles = group.getRealmRoles();
+        Map<String, List<String>> clientRoles = group.getClientRoles();
+        Map<String, List<String>> atrs = group.getAttributes();
+
+        GroupRepresentation representation = GroupRepresentation.newBuilder()
+                .setName(name)
+                .setId(id)
+                .build();
+
+        if (realmRoles != null && !realmRoles.isEmpty()) {
+            representation = representation.toBuilder().addAllRealmRoles(realmRoles).build();
+        }
+
+        if (clientRoles != null && !clientRoles.isEmpty() && !clientRoles.get(clientId).isEmpty()) {
+
+            representation = representation.toBuilder().addAllClientRoles(clientRoles.get(clientId)).build();
+        }
+
+        if (atrs != null && !atrs.isEmpty()) {
+            List<UserAttribute> attributeList = new ArrayList<>();
+            for (String key : atrs.keySet()) {
+                if (key.equals(Constants.OWNER_ID)) {
+                    representation = representation.toBuilder().setOwnerId(atrs.get(key).get(0)).build();
+                } else if (key.equals(Constants.DESCRIPTION)) {
+                    representation = representation.toBuilder().setDescription(atrs.get(key).get(0)).build();
+                } else {
+                    UserAttribute attribute = UserAttribute.newBuilder().setKey(key).addAllValues(atrs.get(key)).build();
+                    attributeList.add(attribute);
+                }
+            }
+            representation = representation.toBuilder().addAllAttributes(attributeList).build();
+
+        }
+
+        if (group.getSubGroups() != null && !group.getSubGroups().isEmpty()) {
+            for (org.keycloak.representations.idm.GroupRepresentation subGroup : group.getSubGroups()) {
+                representation = transformKeycloakGroupToGroup(clientId, subGroup, representation);
+            }
+
+        }
+
+
+        if (parent != null) {
+            parent = parent.toBuilder().addSubGroups(representation).build();
+        }
+
+        if (parent != null) {
+            return parent;
+        } else {
+            return representation;
+        }
+
+    }
+
+
+}
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java
new file mode 100644
index 0000000..20390d2
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/IAMOperations.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.iam.utils;
+
+/**
+ * Includes operations associated with keycloak
+ */
+public enum IAMOperations {
+
+    SET_UP_TENANT,
+    UPDATE_TENANT,
+    REGISTER_USER,
+    ENABLE_USER,
+    DISABLE_USER,
+    DELETE_USER,
+    RESET_PASSWORD,
+    UPDATE_USER_PROFILE,
+    ADD_ROLE_TO_USER,
+    DELETE_ROLE_FROM_USER,
+    CONFIGURE_IDP,
+    REGISTER_ENABLE_USERS,
+    ADD_ROLES_TO_TENANT,
+    ADD_PROTOCOL_MAPPER,
+    ADD_USER_ATTRIBUTE,
+    ADD_ROLES_TO_USERS,
+    DELETE_USER_ATTRIBUTES,
+    CONFIGURE_PERSISTANCE,
+    CREATE_GROUP,
+    UPDATE_GROUP,
+    DELETE_GROUP,
+    ADD_USER_TO_GROUP,
+    REMOVE_USER_FROM_GROUP,
+    CONFIGURE_AGENT_CLIENT,
+    REGISTER_AGENT,
+    ENABLE_AGENT,
+    DISABLE_AGENT,
+    DELETE_AGENT,
+    ADD_ROLE_TO_AGENT,
+    DELETE_ROLE_FROM_AGENT,
+    ADD_AGENT_ATTRIBUTES,
+    DELETE_AGENT_ATTRIBUTES,
+    GRANT_ADMIN_PRIVILEGE,
+    REMOVE_ADMIN_PRIVILEGE
+
+}
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/Status.java b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/Status.java
new file mode 100644
index 0000000..047db8b
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/utils/Status.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.iam.utils;
+
+public final class Status {
+
+    public final static String ACTIVE = "ACTIVE";
+    public final static String PENDING_CONFIRMATION = "PENDING_CONFIRMATION";
+    public final static String CONFIRMED = "CONFIRMED";
+}
diff --git a/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/validator/InputValidator.java b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/validator/InputValidator.java
new file mode 100644
index 0000000..c149ae0
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/java/org/apache/custos/iam/validator/InputValidator.java
@@ -0,0 +1,921 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.iam.validator;
+
+
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.iam.exceptions.MissingParameterException;
+import org.apache.custos.iam.service.*;
+
+import java.util.List;
+
+/**
+ * This class validates the  requests
+ */
+public class InputValidator implements Validator {
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "setUPTenant":
+                validateSetUPTenant(obj);
+                break;
+            case "registerUser":
+                validateRegisterUser(obj);
+                break;
+            case "registerAndEnableUsers":
+                validateRegisterUsers(obj);
+                break;
+            case "enableUser":
+            case "isUserEnabled":
+            case "isUserExist":
+            case "getUser":
+            case "deleteUser":
+            case "isUsernameAvailable":
+            case "grantAdminPrivilege":
+                validateUserAccess(obj);
+                break;
+            case "resetPassword":
+                validateResetPassword(obj);
+                break;
+            case "findUsers":
+                validateFindUsers(obj);
+                break;
+            case "updateUserProfile":
+                validateUpdateUserProfile(obj);
+                break;
+            case "addRoleToUser":
+            case "deleteRolesFromUser":
+                validateDeleteRolesFromUser(obj);
+                break;
+            case "configureFederatedIDP":
+                validateConfigureFederatedIDP(obj);
+                break;
+            case "addRolesToTenant":
+                validateAddRoleToTenant(obj);
+                break;
+            case "addProtocolMapper":
+                validateAddProtocolMapper(obj);
+                break;
+            case "addUserAttributes":
+                validateAddUserAttributes(obj);
+                break;
+
+            case "createGroups":
+                validateCreateGroups(obj);
+                break;
+
+            case "updateGroup":
+                validateUpdateGroup(obj);
+                break;
+            case "deleteGroup":
+                validateDeleteGroup(obj);
+                break;
+
+            case "findGroup":
+                validateFindGroup(obj);
+                break;
+
+            case "getAllGroups":
+                validateGetAllGroups(obj);
+                break;
+
+            case "validateUserGroupMapping":
+                validateUserGroupMapping(obj);
+                break;
+
+            case "createAgentClient":
+                validateCreateAgentClient(obj);
+                break;
+            case "configureAgentClient":
+                configureAgentClient(obj);
+                break;
+            case "isAgentNameAvailable":
+            case "deleteAgent":
+            case "disableAgent":
+            case "enableAgent":
+                validateUserSearchRequestForAgent(obj);
+                break;
+            case "registerAndEnableAgent":
+                validateRegisterAndEnableAgent(obj);
+                break;
+            case "addAgentAttributes":
+                validateAddAgentAttributes(obj);
+                break;
+            case "deleteAgentAttributes":
+                validateDeleteAgentAttributes(obj);
+                break;
+            case "addRolesToAgent":
+                validateAddRolesToAgent(obj);
+                break;
+            case "deleteRolesFromAgent":
+                validateDeleteRolesFromAgent(obj);
+                break;
+            case "getAllResources":
+                validateGetAllResources(obj);
+                break;
+
+
+            default:
+
+        }
+
+    }
+
+    private boolean validateSetUPTenant(Object obj) {
+        if (obj instanceof SetUpTenantRequest) {
+            SetUpTenantRequest request = (SetUpTenantRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAdminFirstname() == null || request.getAdminFirstname().trim().equals("")) {
+                throw new MissingParameterException("Admin firstname should not be null", null);
+            }
+            if (request.getAdminLastname() == null || request.getAdminLastname().trim().equals("")) {
+                throw new MissingParameterException("Admin lastname should not be null", null);
+            }
+            if (request.getAdminEmail() == null || request.getAdminEmail().trim().equals("")) {
+                throw new MissingParameterException("Admin email should not be null", null);
+            }
+            if (request.getAdminPassword() == null || request.getAdminPassword().trim().equals("")) {
+                throw new MissingParameterException("Admin password should not be null", null);
+            }
+            if (request.getAdminUsername() == null || request.getAdminUsername().trim().equals("")) {
+                throw new MissingParameterException("Admin username should not be null", null);
+            }
+            if (request.getTenantName() == null || request.getTenantName().trim().equals("")) {
+                throw new MissingParameterException("Tenant name should not be null", null);
+            }
+            if (request.getTenantURL() == null || request.getTenantURL().trim().equals("")) {
+                throw new MissingParameterException("Tenant URL should not be null", null);
+            }
+            if (request.getRequesterEmail() == null || request.getRequesterEmail().trim().equals("")) {
+                throw new MissingParameterException("Tenant requester email should not be null", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method setUPTenant");
+        }
+        return true;
+    }
+
+
+    private boolean validateRegisterUser(Object obj) {
+        if (obj instanceof RegisterUserRequest) {
+            RegisterUserRequest request = (RegisterUserRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+
+            if (request.getUser() == null || request.getUser().getUsername() == null ||
+                    request.getUser().getUsername().trim().equals("")) {
+                throw new MissingParameterException("Username should not be null", null);
+            }
+
+            if (request.getUser() == null || request.getUser().getFirstName() == null ||
+                    request.getUser().getFirstName().trim().equals("")) {
+                throw new MissingParameterException("Firstname should not be null", null);
+            }
+            if (request.getUser() == null || request.getUser().getLastName() == null ||
+                    request.getUser().getLastName().trim().equals("")) {
+                throw new MissingParameterException("Lastname should not be null", null);
+            }
+            if (request.getUser() == null || request.getUser().getEmail() == null ||
+                    request.getUser().getEmail().trim().equals("")) {
+                throw new MissingParameterException("Email should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method registerUser");
+        }
+        return true;
+    }
+
+    private boolean validateRegisterUsers(Object obj) {
+        if (obj instanceof RegisterUsersRequest) {
+            RegisterUsersRequest usersRequest = (RegisterUsersRequest) obj;
+
+            if (usersRequest.getUsersList().isEmpty()) {
+                throw new MissingParameterException("You need to have at least one User", null);
+            }
+
+            if (usersRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (usersRequest.getAccessToken() == null) {
+                throw new MissingParameterException("Access Token  should not be null", null);
+            }
+
+            if (usersRequest.getClientId() == null) {
+                throw new MissingParameterException("Client Id  should not be null", null);
+            }
+
+            List<UserRepresentation> userRepresentationList = usersRequest.getUsersList();
+
+            for (UserRepresentation user : userRepresentationList) {
+                if (user.getUsername() == null ||
+                        user.getUsername().trim().equals("")) {
+                    throw new MissingParameterException("Username should not be null", null);
+                }
+
+                if (user.getFirstName() == null ||
+                        user.getFirstName().trim().equals("")) {
+                    throw new MissingParameterException("Firstname should not be null", null);
+                }
+                if (user.getLastName() == null ||
+                        user.getLastName().trim().equals("")) {
+                    throw new MissingParameterException("Lastname should not be null", null);
+                }
+                if (user.getEmail() == null ||
+                        user.getEmail().trim().equals("")) {
+                    throw new MissingParameterException("Email should not be null", null);
+                }
+
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method registerUsers");
+        }
+        return true;
+    }
+
+    private boolean validateUserAccess(Object obj) {
+        if (obj instanceof UserSearchRequest) {
+            UserSearchRequest request = (UserSearchRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+
+            if (request.getUser().getUsername() == null || request.getUser().getUsername().trim().equals("")) {
+                throw new MissingParameterException("Username should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method userAccess");
+        }
+        return true;
+    }
+
+
+    private boolean validateResetPassword(Object obj) {
+        if (obj instanceof ResetUserPassword) {
+            ResetUserPassword request = (ResetUserPassword) obj;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+
+            if (request.getUsername() == null || request.getUsername().trim().equals("")) {
+                throw new MissingParameterException("Username should not be null", null);
+            }
+
+            if (request.getPassword() == null || request.getPassword().trim().equals("")) {
+                throw new MissingParameterException("Password should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method resetPassword");
+        }
+        return true;
+    }
+
+    private boolean validateFindUsers(Object obj) {
+        if (obj instanceof FindUsersRequest) {
+            FindUsersRequest request = (FindUsersRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+
+            if (request.getUser() == null) {
+                throw new MissingParameterException("Atleast one user search string is required", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method findUsers");
+        }
+        return true;
+    }
+
+    private boolean validateUpdateUserProfile(Object obj) {
+        if (obj instanceof UpdateUserProfileRequest) {
+            UpdateUserProfileRequest re = (UpdateUserProfileRequest) obj;
+            UserRepresentation request = re.getUser();
+            if (re.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (re.getAccessToken() == null || re.getAccessToken().trim().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+
+            if (request.getUsername() == null || request.getUsername().trim().equals("")) {
+                throw new MissingParameterException("Username should not be null", null);
+            }
+
+            if (request.getFirstName() == null || request.getFirstName().trim().equals("")) {
+                throw new MissingParameterException("Firstname should not be null", null);
+            }
+            if (request.getLastName() == null || request.getLastName().trim().equals("")) {
+                throw new MissingParameterException("Lastname should not be null", null);
+            }
+            if (request.getEmail() == null || request.getEmail().trim().equals("")) {
+                throw new MissingParameterException("Email should not be null", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method updateUserProfile");
+        }
+        return true;
+    }
+
+
+    private boolean validateDeleteRolesFromUser(Object obj) {
+        if (obj instanceof DeleteUserRolesRequest) {
+            DeleteUserRolesRequest request = (DeleteUserRolesRequest) obj;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getUsername() == null || request.getUsername().trim().equals("")) {
+                throw new MissingParameterException("Username should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+
+            if (request.getClientRolesList().isEmpty() && request.getRolesList().isEmpty()) {
+                throw new MissingParameterException("At least client roles or realm roles should not be null", null);
+            }
+
+            if (request.getPerformedBy() == null || request.getPerformedBy().equals("")) {
+                throw new MissingParameterException("Performed By should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method roleOperationsRequest");
+        }
+        return true;
+    }
+
+    private boolean validateConfigureFederatedIDP(Object obj) {
+        if (obj instanceof ConfigureFederateIDPRequest) {
+            ConfigureFederateIDPRequest request = (ConfigureFederateIDPRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getRequesterEmail() == null || request.getRequesterEmail().trim().equals("")) {
+                throw new MissingParameterException("Requester email should not be null", null);
+            }
+
+            if (request.getClientID() == null || request.getClientID().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getClientSec() == null || request.getClientSec().trim().equals("")) {
+                throw new MissingParameterException("Client secret should not be null", null);
+            }
+            if (request.getType() == null) {
+                throw new MissingParameterException("Type should not be null", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method configureFederatedIDP");
+        }
+        return true;
+    }
+
+    private boolean validateAddRoleToTenant(Object obj) {
+        if (obj instanceof AddRolesRequest) {
+            AddRolesRequest request = (AddRolesRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getRolesCount() == 0) {
+                throw new MissingParameterException("There should be at least one role", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+        }
+        return true;
+    }
+
+
+    private boolean validateAddProtocolMapper(Object obj) {
+        if (obj instanceof AddProtocolMapperRequest) {
+            AddProtocolMapperRequest request = (AddProtocolMapperRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getClaimName() == null || request.getClaimName().trim().equals("")) {
+                throw new MissingParameterException("Claim name should not be null", null);
+            }
+            if (request.getMapperType() == null) {
+                throw new MissingParameterException("Mapper Type should not be null", null);
+            }
+
+            if (request.getMapperType().equals(MapperTypes.USER_ATTRIBUTE)) {
+                if (request.getAttributeName() == null || request.getAttributeName().trim().equals("")) {
+                    throw new MissingParameterException("Attribute name should not be null", null);
+                }
+            }
+
+
+            if (request.getName() == null || request.getName().trim().equals("")) {
+                throw new MissingParameterException("Name should not be null", null);
+            }
+
+
+            if (request.getClaimType() == null) {
+                throw new MissingParameterException("Claim Type should not be null", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+        }
+        return true;
+    }
+
+    private boolean validateAddUserAttributes(Object obj) {
+        if (obj instanceof AddUserAttributesRequest) {
+            AddUserAttributesRequest request = (AddUserAttributesRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getAttributesList().isEmpty()) {
+                throw new MissingParameterException("Attributes should not be null", null);
+            }
+
+            if (request.getUsersList().isEmpty()) {
+                throw new MissingParameterException("Users should not be null", null);
+            }
+
+
+            for (UserAttribute attribute : request.getAttributesList()) {
+                if (attribute.getKey() == null || attribute.getKey().equals("")) {
+                    throw new MissingParameterException("Attribute Key should not be null", null);
+                }
+
+                if (attribute.getValuesList().isEmpty()) {
+                    throw new MissingParameterException("Attribute value should not be null", null);
+                }
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+        }
+        return true;
+    }
+
+
+    private boolean validateCreateGroups(Object obj) {
+        if (obj instanceof GroupsRequest) {
+            GroupsRequest request = (GroupsRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getGroupsList().isEmpty()) {
+                throw new MissingParameterException("There should be at least one group representation", null);
+            }
+
+            for (GroupRepresentation groupRepresentation : request.getGroupsList()) {
+                if (groupRepresentation.getName() == null || groupRepresentation.getName().trim().equals("")) {
+                    throw new MissingParameterException("Name should not be null", null);
+                }
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateCreateGroups");
+        }
+        return true;
+
+    }
+
+
+    private boolean validateUpdateGroup(Object obj) {
+        if (obj instanceof GroupRequest) {
+            GroupRequest request = (GroupRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getGroup() == null || request.getGroup().getId() == null ||
+                    request.getGroup().getName().trim().equals("")) {
+                throw new MissingParameterException("Group id and name should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+        }
+        return true;
+    }
+
+
+    private boolean validateDeleteGroup(Object obj) {
+        if (obj instanceof GroupRequest) {
+            GroupRequest request = (GroupRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getGroup() == null || request.getGroup().getId() == null) {
+                throw new MissingParameterException("Group id should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+        }
+        return true;
+    }
+
+
+    private boolean validateFindGroup(Object obj) {
+        if (obj instanceof GroupRequest) {
+            GroupRequest request = (GroupRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getGroup() == null || !(request.getGroup().getId().trim().equals("") ||
+                    request.getGroup().getName().trim().equals(""))) {
+                throw new MissingParameterException("Group id or name should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+        }
+        return true;
+
+    }
+
+
+    private boolean validateGetAllGroups(Object obj) {
+        if (obj instanceof GroupRequest) {
+            GroupRequest request = (GroupRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateAddRoleToTenant");
+        }
+        return true;
+
+    }
+
+    private boolean validateUserGroupMapping(Object obj) {
+        if (obj instanceof UserGroupMappingRequest) {
+            UserGroupMappingRequest request = (UserGroupMappingRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAccessToken() == null || request.getAccessToken().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+            if (request.getGroupId() == null || request.getGroupId().equals("")) {
+                throw new MissingParameterException("Group Id should not be null", null);
+            }
+            if (request.getUsername() == null || request.getUsername().equals("")) {
+                throw new MissingParameterException("Username should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateUserGroupMapping");
+        }
+        return true;
+
+    }
+
+    private boolean validateCreateAgentClient(Object obj) {
+        if (obj instanceof AgentClientMetadata) {
+            AgentClientMetadata request = (AgentClientMetadata) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+            if (request.getAccessToken() == null || request.getAccessToken().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+            if (request.getRedirectURIsCount() == 0) {
+                throw new MissingParameterException("Atleast one redirect URI should be there", null);
+            }
+            if (request.getClientName() == null || request.getClientName().equals("")) {
+                throw new MissingParameterException("Client name should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateUserGroupMapping");
+        }
+        return true;
+    }
+
+    private boolean configureAgentClient(Object obj) {
+        if (obj instanceof AgentClientMetadata) {
+            AgentClientMetadata request = (AgentClientMetadata) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientName() == null || request.getClientName().equals("")) {
+                throw new MissingParameterException("Client name should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateUserGroupMapping");
+        }
+        return true;
+    }
+
+
+    private boolean validateUserSearchRequestForAgent(Object obj) {
+        if (obj instanceof UserSearchRequest) {
+            UserSearchRequest request = (UserSearchRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAccessToken() == null || request.getAccessToken().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+            if (request.getUser() == null) {
+                throw new MissingParameterException("Agent  should not be null", null);
+            }
+            if (request.getUser().getId() == null || request.getUser().getId().equals("")) {
+                throw new MissingParameterException("Agent Id should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for request UserSearchRequest");
+        }
+        return true;
+    }
+
+    private boolean validateRegisterAndEnableAgent(Object obj) {
+        if (obj instanceof RegisterUserRequest) {
+            RegisterUserRequest request = (RegisterUserRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+            if (request.getAccessToken() == null || request.getAccessToken().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+            if (request.getUser() == null) {
+                throw new MissingParameterException(" Agent should not be null", null);
+            }
+            if (request.getUser().getId() == null || request.getUser().getId().equals("")) {
+                throw new MissingParameterException("Agent Id should not be null", null);
+            }
+
+            if (request.getUser().getPassword() == null || request.getUser().getPassword().equals("")) {
+                throw new MissingParameterException("Agent password should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateRegisterAndEnableAgent");
+        }
+        return true;
+    }
+
+
+    private boolean validateDeleteAgentAttributes(Object obj) {
+        if (obj instanceof DeleteUserAttributeRequest) {
+            DeleteUserAttributeRequest request = (DeleteUserAttributeRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAccessToken() == null || request.getAccessToken().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+            if (request.getAttributesList().isEmpty()) {
+                throw new MissingParameterException("Attributes should not be null", null);
+            }
+
+            if (request.getAgentsList().isEmpty()) {
+                throw new MissingParameterException("Agents should not be null", null);
+            }
+
+
+            for (UserAttribute attribute : request.getAttributesList()) {
+                if (attribute.getKey() == null || attribute.getKey().equals("")) {
+                    throw new MissingParameterException("Attribute Key should not be null", null);
+                }
+
+                if (attribute.getValuesList().isEmpty()) {
+                    throw new MissingParameterException("Attribute value should not be null", null);
+                }
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateUserGroupMapping");
+        }
+        return true;
+    }
+
+    private boolean validateAddAgentAttributes(Object obj) {
+        if (obj instanceof AddUserAttributesRequest) {
+            AddUserAttributesRequest request = (AddUserAttributesRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAccessToken() == null || request.getAccessToken().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+            if (request.getAttributesList().isEmpty()) {
+                throw new MissingParameterException("Attributes should not be null", null);
+            }
+
+            if (request.getAgentsList().isEmpty()) {
+                throw new MissingParameterException("Agents should not be null", null);
+            }
+
+
+            for (UserAttribute attribute : request.getAttributesList()) {
+                if (attribute.getKey() == null || attribute.getKey().equals("")) {
+                    throw new MissingParameterException("Attribute Key should not be null", null);
+                }
+
+                if (attribute.getValuesList().isEmpty()) {
+                    throw new MissingParameterException("Attribute value should not be null", null);
+                }
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateUserGroupMapping");
+        }
+        return true;
+    }
+
+
+    private boolean validateAddRolesToAgent(Object obj) {
+        if (obj instanceof AddUserRolesRequest) {
+            AddUserRolesRequest request = (AddUserRolesRequest) obj;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getAgentsCount() == 0) {
+                throw new MissingParameterException("At least one agent id should present", null);
+            }
+
+
+            if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+
+            if (request.getRolesList().isEmpty() && request.getRolesList().isEmpty()) {
+                throw new MissingParameterException("At least client roles or realm roles should not be null", null);
+            }
+
+            if (request.getPerformedBy() == null || request.getPerformedBy().equals("")) {
+                throw new MissingParameterException("Performed By should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method roleOperationsRequest");
+        }
+        return true;
+
+    }
+
+    private boolean validateDeleteRolesFromAgent(Object obj) {
+        if (obj instanceof DeleteUserRolesRequest) {
+            DeleteUserRolesRequest request = (DeleteUserRolesRequest) obj;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getId() == null || request.getId().trim().equals("")) {
+                throw new MissingParameterException("Agent Id should not be null", null);
+            }
+
+
+            if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+
+            if (request.getClientRolesList().isEmpty() && request.getRolesList().isEmpty()) {
+                throw new MissingParameterException("At least client roles or realm roles should not be null", null);
+            }
+
+            if (request.getPerformedBy() == null || request.getPerformedBy().equals("")) {
+                throw new MissingParameterException("Performed By should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method roleOperationsRequest");
+        }
+        return true;
+    }
+
+
+    private boolean validateGetAllResources(Object obj) {
+        if (obj instanceof GetAllResources) {
+            GetAllResources request = (GetAllResources) obj;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getResourceType() == null) {
+                throw new MissingParameterException("Resource  type should not be null", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method getAllResources");
+        }
+        return true;
+    }
+
+}
diff --git a/custos-core-services/iam-admin-core-service/src/main/proto/IamAdminService.proto b/custos-core-services/iam-admin-core-service/src/main/proto/IamAdminService.proto
new file mode 100644
index 0000000..63a77fe
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/proto/IamAdminService.proto
@@ -0,0 +1,469 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.iam.service;
+
+import "google/protobuf/empty.proto";
+
+
+enum FederatedIDPs {
+    CILOGON = 0;
+    FACEBOOK = 1;
+    GOOGLE = 2;
+    LINKEDIN = 3;
+    TWITTER = 4;
+    CUSTOM_OIDC = 5;
+}
+
+
+message SetUpTenantRequest {
+    int64 tenantId = 1;
+    string tenantName = 2;
+    string adminUsername = 3;
+    string adminFirstname = 4;
+    string adminLastname = 5;
+    string adminEmail = 6;
+    string adminPassword = 7;
+    string tenantURL = 8;
+    string requesterEmail = 9;
+    repeated string redirectURIs = 10;
+    string custosClientId = 11;
+
+}
+
+message ConfigureFederateIDPRequest {
+    int64 tenantId = 1;
+    FederatedIDPs type = 2;
+    string clientID = 3;
+    string clientSec = 4;
+    map<string, string> configMap = 5;
+    string requesterEmail = 6;
+    string idpId = 7;
+    string scope = 8;
+}
+
+
+message FederateIDPResponse {
+    bool status = 1;
+}
+
+message SetUpTenantResponse {
+    string clientId = 1;
+    string clientSecret = 2;
+}
+
+message IsUsernameAvailableRequest {
+    int64 tenantId = 1;
+    string accessToken = 2;
+    string userName = 3;
+
+}
+
+message CheckingResponse {
+    bool is_exist = 1;
+}
+
+
+message UserRepresentation {
+    string id = 1;
+    string username = 3;
+    string first_name = 4;
+    string last_name = 5;
+    string password = 6;
+    string email = 7;
+    bool temporary_password = 8;
+    repeated string realm_roles = 9;
+    repeated string client_roles = 10;
+    repeated UserAttribute attributes = 11;
+    string state = 12;
+    double creation_time = 13;
+    double last_login_at = 14;
+}
+
+
+message GroupRepresentation {
+    string name = 1;
+    string id = 2;
+    repeated string realm_roles = 3;
+    repeated string client_roles = 4;
+    repeated UserAttribute attributes = 5;
+    repeated UserRepresentation users = 6;
+    repeated GroupRepresentation sub_groups = 7;
+    string description = 8;
+    string ownerId = 9;
+}
+
+
+message RegisterUserRequest {
+    int64 tenantId = 1;
+    string accessToken = 2;
+    string clientId = 3;
+    string clientSec = 4;
+    UserRepresentation user = 5;
+    string performedBy = 6;
+}
+
+
+message RegisterUsersRequest {
+    repeated UserRepresentation users = 1;
+    int64 tenantId = 2;
+    string accessToken = 3;
+    string clientId = 4;
+    string performedBy = 5;
+}
+
+message RegisterUserResponse {
+    bool is_registered = 1;
+}
+
+message RegisterUsersResponse {
+    bool allUseresRegistered = 1;
+    repeated UserRepresentation failedUsers = 2;
+}
+
+
+message UserSearchMetadata {
+    string username = 1;
+    string first_name = 2;
+    string last_name = 3;
+    string email = 4;
+    string id = 5;
+}
+
+message FindUsersRequest {
+    UserSearchMetadata user = 3;
+    int32 offset = 4;
+    int32 limit = 5;
+    int64 tenantId = 1;
+    string accessToken = 2;
+    string client_id = 6;
+    string client_sec = 7;
+
+}
+
+message UserSearchRequest {
+    UserSearchMetadata user = 1;
+    int64 tenantId = 2;
+    string accessToken = 3;
+    string client_id = 4;
+    string client_sec = 5;
+    string performedBy = 6;
+}
+
+message FindUsersResponse {
+    repeated UserRepresentation users = 1;
+}
+
+message ResetUserPassword {
+    string username = 1;
+    string password = 2;
+    int64 tenantId = 3;
+    string accessToken = 4;
+    string clientId = 5;
+    string clientSec = 6;
+}
+
+
+message DeleteUserRolesRequest {
+    int64 tenant_id = 1;
+    string username = 2;
+    repeated string client_roles = 3;
+    repeated string roles = 4;
+    string access_token = 5;
+    string client_id = 6;
+    string performed_by = 7;
+    string id = 8;
+}
+
+message AddUserRolesRequest {
+    int64 tenant_id = 1;
+    repeated string usernames = 2;
+    repeated string roles = 3;
+    string access_token = 4;
+    string client_id = 5;
+    bool client_level = 6;
+    string performed_by = 7;
+    repeated string agents = 8;
+}
+
+message UpdateUserProfileRequest {
+    string accessToken = 1;
+    int64 tenantId = 2;
+    UserRepresentation user = 3;
+
+}
+
+message AddUserResponse {
+    string code = 1;
+}
+
+message GetOperationsMetadataRequest {
+    int64 traceId = 1;
+}
+
+message OperationMetadata {
+    string event = 1;
+    string status = 2;
+    string timeStamp = 3;
+    string performedBy = 4;
+}
+message GetOperationsMetadataResponse {
+    repeated OperationMetadata metadata = 1;
+}
+
+message DeleteTenantRequest {
+    int64 tenantId = 1;
+}
+
+message AddRolesRequest {
+    repeated RoleRepresentation roles = 1;
+    bool client_level = 2;
+    int64 tenant_id = 3;
+    string client_id = 4;
+}
+
+message GetRolesRequest {
+    bool client_level = 1;
+    int64 tenant_id = 2;
+    string client_id = 3;
+}
+
+message RoleRepresentation {
+    string name = 1;
+    string description = 2;
+    bool composite = 3;
+
+
+}
+
+message AllRoles {
+    repeated RoleRepresentation roles = 1;
+    string scope = 2;
+}
+
+message AddProtocolMapperRequest {
+    string name = 1;
+    string attribute_name = 2;
+    string claim_name = 3;
+    ClaimJSONTypes claim_type = 4;
+    int64 tenant_id = 6;
+    string client_id = 7;
+    MapperTypes mapper_type = 8;
+    bool add_to_id_token = 9;
+    bool add_to_access_token = 10;
+    bool add_to_user_info = 11;
+    bool multi_valued = 12;
+    bool aggregate_attribute_values = 13;
+}
+
+enum MapperTypes {
+    USER_ATTRIBUTE = 0;
+    USER_REALM_ROLE = 1;
+    USER_CLIENT_ROLE = 2;
+}
+
+enum ClaimJSONTypes {
+    STRING = 0;
+    LONG = 1;
+    INTEGER = 2;
+    BOOLEAN = 3;
+    JSON = 4;
+}
+
+enum ResourceTypes {
+    USER =0;
+    AGENT = 1;
+}
+
+message OperationStatus {
+    bool status = 1;
+}
+
+message AddUserAttributesRequest {
+    repeated UserAttribute attributes = 1;
+    repeated string users = 2;
+    int64 tenant_id = 3;
+    string client_id = 4;
+    string access_token = 5;
+    string performedBy = 6;
+    repeated string agents = 7;
+}
+
+message DeleteUserAttributeRequest {
+    repeated UserAttribute attributes = 1;
+    repeated string users = 2;
+    int64 tenant_id = 3;
+    string client_id = 4;
+    string access_token = 5;
+    string performedBy = 6;
+    repeated string agents = 7;
+}
+
+message UserAttribute {
+    string key = 1;
+    repeated string values = 2;
+}
+
+message EventPersistenceRequest {
+    int64 tenantId = 1;
+    bool admin_event = 2;
+    string event = 3;
+    bool enable = 4;
+    int64 persistence_time = 5;
+    string performedBy = 6;
+}
+
+
+message GroupsRequest {
+    int64 tenantId = 1;
+    string accessToken = 2;
+    string performedBy = 3;
+    string clientId = 4;
+    string clientSec = 5;
+    repeated GroupRepresentation groups = 6;
+}
+
+message GroupRequest {
+    int64 tenantId = 1;
+    string accessToken = 2;
+    string performedBy = 3;
+    string clientId = 4;
+    string clientSec = 5;
+    string id = 6;
+    GroupRepresentation group = 7;
+}
+
+message GroupsResponse {
+    repeated GroupRepresentation groups = 1;
+}
+
+message UserGroupMappingRequest {
+    int64 tenantId = 1;
+    string accessToken = 2;
+    string performedBy = 3;
+    string clientId = 4;
+    string clientSec = 5;
+    string username = 6;
+    string group_id = 7;
+    string membership_type = 8;
+}
+
+message AgentClientMetadata {
+    int64 tenantId = 1;
+    string tenantURL = 2;
+    repeated string redirectURIs = 3;
+    string clientName = 4;
+    int64 access_token_life_time = 5;
+    string performedBy = 6;
+    string access_token = 7;
+}
+
+message Agent {
+    string id = 1;
+    repeated string realm_roles = 2;
+    repeated UserAttribute attributes = 3;
+    bool isEnabled = 4;
+    double creation_time = 5;
+    double last_modified_at = 6;
+    repeated string client_roles = 7;
+}
+
+
+message GetAllResources {
+    int64 tenantId = 1;
+    string clientId = 2;
+    ResourceTypes resource_type = 3;
+}
+
+message GetAllResourcesResponse {
+    repeated Agent agents = 1;
+    repeated UserRepresentation users = 2;
+}
+
+
+service IamAdminService {
+
+    rpc setUPTenant (SetUpTenantRequest) returns (SetUpTenantResponse);
+    rpc updateTenant (SetUpTenantRequest) returns (SetUpTenantResponse);
+    rpc deleteTenant (DeleteTenantRequest) returns (google.protobuf.Empty);
+    rpc configureFederatedIDP (ConfigureFederateIDPRequest) returns (FederateIDPResponse);
+    rpc addRolesToTenant (AddRolesRequest) returns (AllRoles);
+    rpc addProtocolMapper (AddProtocolMapperRequest) returns (OperationStatus);
+    rpc getRolesOfTenant (GetRolesRequest) returns (AllRoles);
+
+    rpc isUsernameAvailable (UserSearchRequest) returns (OperationStatus);
+    rpc registerUser (RegisterUserRequest) returns (RegisterUserResponse);
+    rpc enableUser (UserSearchRequest) returns (UserRepresentation);
+    rpc disableUser (UserSearchRequest) returns (UserRepresentation);
+    rpc isUserEnabled (UserSearchRequest) returns (OperationStatus);
+    rpc isUserExist (UserSearchRequest) returns (CheckingResponse);
+    rpc getUser (UserSearchRequest) returns (UserRepresentation);
+    rpc findUsers (FindUsersRequest) returns (FindUsersResponse);
+    rpc resetPassword (ResetUserPassword) returns (OperationStatus);
+    rpc grantAdminPrivilege (UserSearchRequest) returns (OperationStatus);
+    rpc removeAdminPrivilege (UserSearchRequest) returns (OperationStatus);
+
+    rpc registerAndEnableUsers (RegisterUsersRequest) returns (RegisterUsersResponse);
+    rpc addUserAttributes (AddUserAttributesRequest) returns (OperationStatus);
+    rpc deleteUserAttributes (DeleteUserAttributeRequest) returns (OperationStatus);
+    rpc addRolesToUsers (AddUserRolesRequest) returns (OperationStatus);
+
+    rpc deleteUser (UserSearchRequest) returns (OperationStatus);
+
+    rpc deleteRolesFromUser (DeleteUserRolesRequest) returns (OperationStatus);
+
+    rpc updateUserProfile (UpdateUserProfileRequest) returns (OperationStatus);
+
+    rpc getOperationMetadata (GetOperationsMetadataRequest) returns (GetOperationsMetadataResponse);
+
+    rpc configureEventPersistence (EventPersistenceRequest) returns (OperationStatus);
+
+    rpc createGroups (GroupsRequest) returns (GroupsResponse);
+    rpc updateGroup (GroupRequest) returns (GroupRepresentation);
+    rpc deleteGroup (GroupRequest) returns (OperationStatus);
+    rpc findGroup (GroupRequest) returns (GroupRepresentation);
+    rpc getAllGroups (GroupRequest) returns (GroupsResponse);
+
+    rpc addUserToGroup (UserGroupMappingRequest) returns (OperationStatus);
+    rpc removeUserFromGroup (UserGroupMappingRequest) returns (OperationStatus);
+
+    rpc createAgentClient (AgentClientMetadata) returns (SetUpTenantResponse);
+    rpc configureAgentClient (AgentClientMetadata) returns (OperationStatus);
+
+
+    rpc isAgentNameAvailable (UserSearchRequest) returns (OperationStatus);
+    rpc registerAndEnableAgent (RegisterUserRequest) returns (RegisterUserResponse);
+    rpc deleteAgent (UserSearchRequest) returns (OperationStatus);
+    rpc getAgent (UserSearchRequest) returns (Agent);
+    rpc disableAgent (UserSearchRequest) returns (OperationStatus);
+    rpc enableAgent (UserSearchRequest) returns (OperationStatus);
+    rpc addAgentAttributes (AddUserAttributesRequest) returns (OperationStatus);
+    rpc deleteAgentAttributes (DeleteUserAttributeRequest) returns (OperationStatus);
+    rpc addRolesToAgent (AddUserRolesRequest) returns (OperationStatus);
+    rpc deleteAgentRoles (DeleteUserRolesRequest) returns (OperationStatus);
+
+
+    rpc getAllResources (GetAllResources) returns (GetAllResourcesResponse);
+
+
+}
\ No newline at end of file
diff --git a/custos-core-services/iam-admin-core-service/src/main/resources/application.properties b/custos-core-services/iam-admin-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..8453f69
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/resources/application.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=iamAdminCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_iam?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
\ No newline at end of file
diff --git a/custos-core-services/iam-admin-core-service/src/main/resources/bootstrap.properties b/custos-core-services/iam-admin-core-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..760bf92
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+spring.profiles.active:default
\ No newline at end of file
diff --git a/custos-core-services/iam-admin-core-service/src/main/resources/keycloak-client-truststore.pkcs12 b/custos-core-services/iam-admin-core-service/src/main/resources/keycloak-client-truststore.pkcs12
new file mode 100644
index 0000000..9d74713
--- /dev/null
+++ b/custos-core-services/iam-admin-core-service/src/main/resources/keycloak-client-truststore.pkcs12
Binary files differ
diff --git a/custos-core-services/identity-core-service/Dockerfile b/custos-core-services/identity-core-service/Dockerfile
new file mode 100644
index 0000000..7271b96
--- /dev/null
+++ b/custos-core-services/identity-core-service/Dockerfile
@@ -0,0 +1,6 @@
+FROM openjdk:11-jre-slim
+COPY src/main/resources/keycloak-client-truststore.pkcs12 /home/ubuntu/keystore/keycloak-client-truststore.pkcs12
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/identity-core-service/pom.xml b/custos-core-services/identity-core-service/pom.xml
new file mode 100644
index 0000000..0d9c7ee
--- /dev/null
+++ b/custos-core-services/identity-core-service/pom.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>identity-core-service</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-federated-services-clients</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java-util</artifactId>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/identity-core-service/src/main/helm/.helmignore b/custos-core-services/identity-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/identity-core-service/src/main/helm/Chart.yaml b/custos-core-services/identity-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..f9cac55
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of custos identity service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/identity-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/identity-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/identity-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/identity-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/identity-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/identity-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..31e54a6
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,64 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/identity-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/identity-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/identity-core-service/src/main/helm/templates/service.yaml b/custos-core-services/identity-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/identity-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/identity-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/identity-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/identity-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/identity-core-service/src/main/helm/values.yaml b/custos-core-services/identity-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..93eb74d
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/helm/values.yaml
@@ -0,0 +1,78 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/IdentityServiceInitializer.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/IdentityServiceInitializer.java
new file mode 100644
index 0000000..f3a5923
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/IdentityServiceInitializer.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.apache.custos.identity.validator.InputValidator;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableJpaRepositories(basePackages = "org.apache.custos")
+@ComponentScan(basePackages = "org.apache.custos")
+@EntityScan(basePackages = "org.apache.custos")
+public class IdentityServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(IdentityServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator){
+        return new ServiceInterceptor(validator);
+    }
+
+}
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCache.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCache.java
new file mode 100644
index 0000000..634965f
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCache.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.custos.identity.authzcache;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@Component
+public class AuthzCache extends LinkedHashMap<AuthzCacheIndex, AuthzCacheEntry> {
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(AuthzCache.class);
+
+    private int MAX_SIZE;
+
+    public AuthzCache(@Value("${custos.identity.auth.cache.size:1024}") int initialCapacity) {
+        super(initialCapacity);
+        MAX_SIZE = initialCapacity;
+    }
+
+    @Override
+    protected boolean removeEldestEntry(Map.Entry<AuthzCacheIndex, AuthzCacheEntry> eldest) {
+        if (size() > MAX_SIZE) {
+            LOGGER.info("Authz cache max size exceeded. Removing the old entries.");
+        }
+        return size() > MAX_SIZE;
+    }
+}
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCacheEntry.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCacheEntry.java
new file mode 100644
index 0000000..9b6840a
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCacheEntry.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.custos.identity.authzcache;
+
+/**
+ * Cache entry in the default authorization cache.
+ */
+public class AuthzCacheEntry {
+    //authorization decision for the authorization request associated with this cache entry.
+    private boolean decision;
+    //time to live value for the access token in seconds.
+    private long expiryTime;
+    //time stamp in milli seconds at the time this entry is put into the cache
+    private long entryTimestamp;
+
+    public AuthzCacheEntry(boolean decision, long expiryTime, long entryTimestamp) {
+        this.decision = decision;
+        this.expiryTime = expiryTime;
+        this.entryTimestamp = entryTimestamp;
+    }
+
+    public long getEntryTimestamp() {
+        return entryTimestamp;
+    }
+
+    public void setEntryTimestamp(long entryTimestamp) {
+        this.entryTimestamp = entryTimestamp;
+    }
+
+    public long getExpiryTime() {
+        return expiryTime;
+    }
+
+    public void setExpiryTime(long timestamp) {
+        this.expiryTime = timestamp;
+    }
+
+    public boolean getDecision() {
+        return decision;
+    }
+
+    public void setDecision(boolean decision) {
+        this.decision = decision;
+    }
+}
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCacheIndex.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCacheIndex.java
new file mode 100644
index 0000000..db68ac9
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCacheIndex.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.custos.identity.authzcache;
+
+/**
+ * Cache index of the default authorization cache.
+ */
+public class AuthzCacheIndex {
+
+    private String subject;
+    private String oauthAccessToken;
+//    private String action;
+    private String gatewayId;
+
+    public AuthzCacheIndex(String userName, String gatewayId, String accessToken) {
+        this.subject = userName;
+        this.oauthAccessToken = accessToken;
+//        this.action = actionString;
+        this.gatewayId = gatewayId;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+//    public String getAction() {
+//        return action;
+//    }
+//
+//    public void setAction(String action) {
+//        this.action = action;
+//    }
+
+    public String getOauthAccessToken() {
+        return oauthAccessToken;
+    }
+
+    public void setOauthAccessToken(String oauthAccessToken) {
+        this.oauthAccessToken = oauthAccessToken;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    /*Equals and hash code methods are overridden since this is being used as an index of a map and that containsKey method
+        * should return true if the values of two index objects are equal.*/
+    @Override
+    public boolean equals(Object other) {
+        if (other == null || other.getClass() != getClass()) {
+            return false;
+        }
+        return ((this.getSubject().equals(((AuthzCacheIndex) other).getSubject()))
+                && (this.getGatewayId().equals(((AuthzCacheIndex) other).getGatewayId()))
+                && (this.getOauthAccessToken().equals(((AuthzCacheIndex) other).getOauthAccessToken())));
+                //&& (this.getAction().equals(((AuthzCacheIndex) other).getAction())));
+    }
+
+    @Override
+    public int hashCode() {
+        return this.getSubject().hashCode() + this.getOauthAccessToken().hashCode() + this.getGatewayId().hashCode();
+                //+ this.getAction().hashCode();
+    }
+}
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCacheManager.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCacheManager.java
new file mode 100644
index 0000000..e1594b9
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCacheManager.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.custos.identity.authzcache;
+
+
+import org.apache.custos.identity.exceptions.CustosSecurityException;
+
+/**
+ * This is the interface through which security manager accesses the underlying caching implementation
+ * See the DefaultAuthzCacheManager.java for an example implementation of this interface.
+ */
+public interface AuthzCacheManager {
+    /**
+     * Returns the status of the cache w.r.t the given authorization request which is encapsulated in
+     * the AuthzCacheIndex.
+     *
+     * @param authzCacheIndex
+     * @return
+     */
+    public AuthzCachedStatus getAuthzCachedStatus(AuthzCacheIndex authzCacheIndex) throws CustosSecurityException;
+
+    /**
+     * Add to cache the authorization decision pertaining to a given authorization request.
+     *
+     * @param authzCacheIndex
+     * @param authzCacheEntry
+     * @throws CustosSecurityException
+     */
+    public void addToAuthzCache(AuthzCacheIndex authzCacheIndex, AuthzCacheEntry authzCacheEntry) throws CustosSecurityException;
+
+    /**
+     * Check if a valid decision is cached for a given authorization request.
+     *
+     * @param authzCacheIndex
+     * @return
+     */
+    public boolean isAuthzDecisionCached(AuthzCacheIndex authzCacheIndex) throws CustosSecurityException;
+
+    /**
+     * Returns the AuthzCacheEntry for a given authorization request.
+     *
+     * @param authzCacheIndex
+     * @return
+     * @throws CustosSecurityException
+     */
+    public AuthzCacheEntry getAuthzCacheEntry(AuthzCacheIndex authzCacheIndex) throws CustosSecurityException;
+
+    /**
+     * Removes the authorization cache entry for a given authorization request.
+     *
+     * @param authzCacheIndex
+     * @throws CustosSecurityException
+     */
+    public void removeAuthzCacheEntry(AuthzCacheIndex authzCacheIndex) throws CustosSecurityException;
+
+    /**
+     * Clear the authorization cache.
+     *
+     * @return
+     */
+    public void clearCache() throws CustosSecurityException;
+
+}
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCachedStatus.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCachedStatus.java
new file mode 100644
index 0000000..cded519
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/AuthzCachedStatus.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.custos.identity.authzcache;
+
+/**
+ * This enum defines the status of the authorization cache returned by the authorization cache manager
+ * when an authorization status is checked against an authorization request.
+ */
+public enum AuthzCachedStatus {
+    /*Authorization decision is cached for the given authrization request and the decision authorizes the request.*/
+    AUTHORIZED,
+    /*Authorization decision is cached for the given authorization request and the decision denies authorization.*/
+    NOT_AUTHORIZED,
+    /*Authorization decision is not either cached or the cached entry is invalid such that re-authorization is needed.*/
+    NOT_CACHED
+}
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/DefaultAuthzCacheManager.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/DefaultAuthzCacheManager.java
new file mode 100644
index 0000000..19f485a
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/authzcache/DefaultAuthzCacheManager.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.custos.identity.authzcache;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DefaultAuthzCacheManager implements AuthzCacheManager {
+
+    @Autowired
+    private AuthzCache cache;
+
+
+    @Override
+    public AuthzCachedStatus getAuthzCachedStatus(AuthzCacheIndex authzCacheIndex) {
+        if (isAuthzDecisionCached(authzCacheIndex)) {
+            AuthzCacheEntry cacheEntry = getAuthzCacheEntry(authzCacheIndex);
+            long expiryTime = cacheEntry.getExpiryTime();
+            long currentTime = System.currentTimeMillis();
+            long timePassed = (currentTime - cacheEntry.getEntryTimestamp()) / 1000;
+            if (expiryTime > timePassed) {
+                //access token is still valid. Hence, return the cached decision
+                if (cacheEntry.getDecision()) {
+                    return AuthzCachedStatus.AUTHORIZED;
+                } else {
+                    return AuthzCachedStatus.NOT_AUTHORIZED;
+                }
+            } else {
+                //access token has been expired. Hence, remove the entry and return.
+                removeAuthzCacheEntry(authzCacheIndex);
+                return AuthzCachedStatus.NOT_CACHED;
+            }
+        } else {
+            return AuthzCachedStatus.NOT_CACHED;
+        }
+    }
+
+    @Override
+    public void addToAuthzCache(AuthzCacheIndex authzCacheIndex, AuthzCacheEntry authzCacheEntry) {
+        cache.put(authzCacheIndex, authzCacheEntry);
+    }
+
+    @Override
+    public boolean isAuthzDecisionCached(AuthzCacheIndex authzCacheIndex) {
+        return cache.containsKey(authzCacheIndex);
+    }
+
+    @Override
+    public AuthzCacheEntry getAuthzCacheEntry(AuthzCacheIndex authzCacheIndex) {
+        return cache.get(authzCacheIndex);
+    }
+
+    @Override
+    public void removeAuthzCacheEntry(AuthzCacheIndex authzCacheIndex) {
+        cache.remove(authzCacheIndex);
+    }
+
+    @Override
+    public void clearCache() {
+        cache.clear();
+    }
+}
\ No newline at end of file
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/exceptions/CustosSecurityException.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/exceptions/CustosSecurityException.java
new file mode 100644
index 0000000..4d380a7
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/exceptions/CustosSecurityException.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.exceptions;
+
+public class CustosSecurityException extends Exception{
+
+    public CustosSecurityException(String message) {
+        super(message);
+    }
+}
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/service/IdentityService.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/service/IdentityService.java
new file mode 100644
index 0000000..3269182
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/service/IdentityService.java
@@ -0,0 +1,449 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.service;
+
+
+import com.google.protobuf.Struct;
+import com.google.protobuf.util.JsonFormat;
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.federated.services.clients.keycloak.auth.KeycloakAuthClient;
+import org.apache.custos.identity.authzcache.AuthzCacheEntry;
+import org.apache.custos.identity.authzcache.AuthzCacheIndex;
+import org.apache.custos.identity.authzcache.AuthzCachedStatus;
+import org.apache.custos.identity.authzcache.DefaultAuthzCacheManager;
+import org.apache.custos.identity.exceptions.CustosSecurityException;
+import org.apache.custos.identity.service.IdentityServiceGrpc.IdentityServiceImplBase;
+import org.apache.custos.identity.utils.Constants;
+import org.apache.http.HttpStatus;
+import org.json.JSONObject;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+
+/**
+ * A service responsible for authenticate and authorize users
+ */
+@GRpcService
+public class IdentityService extends IdentityServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(IdentityService.class);
+
+    private static final int CACHE_LIFE_TIME = 1000 * 60 * 60;
+
+
+    @Autowired
+    private KeycloakAuthClient keycloakAuthClient;
+
+    @Autowired
+    private DefaultAuthzCacheManager authzCacheManager;
+
+    @Value("${custos.identity.auth.cache.enabled:false}")
+    private boolean isAuthzCacheEnabled;
+
+
+    @Override
+    public void authenticate(AuthenticationRequest request,
+                             StreamObserver<AuthToken> responseObserver) {
+        try {
+            LOGGER.debug("Authentication request received for " + request.getUsername());
+            String accessToken = keycloakAuthClient.authenticate(
+                    request.getClientId(), request.getClientSecret(),
+                    String.valueOf(request.getTenantId()), request.getUsername(), request.getPassword());
+
+            if (accessToken != null) {
+                AuthToken.Builder authzBuilder = AuthToken.newBuilder()
+                        .setAccessToken(accessToken);
+
+                AuthToken token = authzBuilder.build();
+
+                responseObserver.onNext(token);
+                responseObserver.onCompleted();
+
+            } else {
+                responseObserver.onError(Status.UNAUTHENTICATED.asRuntimeException());
+            }
+
+        } catch (org.keycloak.authorization.client.util.HttpResponseException ex) {
+            String msg = "Error occurred while authenticating  user " + request.getUsername() + " " + ex.getReasonPhrase();
+            LOGGER.error(msg);
+            if (ex.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(ex.getReasonPhrase()).asRuntimeException());
+            }
+        } catch (Exception ex) {
+            String msg = "Error occurred while authenticating  user " + request.getUsername() + " " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+
+    @Override
+    public void getUser(AuthToken request,
+                        StreamObserver<org.apache.custos.identity.service.User> responseObserver) {
+        String username = null;
+        String tenantId = null;
+        try {
+            for (Claim claim : request.getClaimsList()) {
+                if (claim.getKey().equals("username")) {
+                    username = claim.getValue();
+                } else if (claim.getKey().equals("tenantId")) {
+                    tenantId = claim.getValue();
+                }
+            }
+
+            LOGGER.debug("Get user request received for " + username);
+
+            org.apache.custos.federated.services.clients.keycloak.auth.User user = keycloakAuthClient.
+                    getUser(request.getAccessToken(), tenantId);
+            org.apache.custos.identity.service.User user1 =
+                    org.apache.custos.identity.service.User.newBuilder()
+                            .setEmailAddress(user.getEmailAddress())
+                            .setFirstName(user.getFirstName())
+                            .setLastName(user.getLastName())
+                            .setFullName(user.getFullName())
+                            .setSub(user.getSub())
+                            .setUsername(user.getUsername())
+                            .build();
+            responseObserver.onNext(user1);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching  user " + username + " " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void isAuthenticate(AuthToken request,
+                               StreamObserver<IsAuthenticateResponse> responseObserver) {
+        String username = null;
+        String tenantId = null;
+
+        for (Claim claim : request.getClaimsList()) {
+            if (claim.getKey().equals("username")) {
+                username = claim.getValue();
+            } else if (claim.getKey().equals("tenantId")) {
+                tenantId = claim.getValue();
+            }
+        }
+        LOGGER.debug("Authentication status checking for  " + username
+        );
+        String accessToken = request.getAccessToken();
+
+
+        boolean isAuthenticated = false;
+
+        try {
+            if (isAuthzCacheEnabled) {
+
+                //check in the cache
+                AuthzCachedStatus authzCachedStatus = authzCacheManager.getAuthzCachedStatus(
+                        new AuthzCacheIndex(username, tenantId, accessToken));
+
+                if (AuthzCachedStatus.AUTHORIZED.equals(authzCachedStatus)) {
+                    LOGGER.debug("Authz decision for: (" + username + ", " + accessToken + ") is retrieved from cache.");
+                    isAuthenticated = true;
+                } else if (AuthzCachedStatus.NOT_AUTHORIZED.equals(authzCachedStatus)) {
+                    LOGGER.debug("Authz decision for: (" + username + ", " + accessToken + ") is retrieved from cache.");
+                    isAuthenticated = false;
+                } else if (AuthzCachedStatus.NOT_CACHED.equals(authzCachedStatus)) {
+                    LOGGER.debug("Authz decision for: (" + username + ", " + accessToken + ") is not in the cache. " +
+                            "Generating decision based on group membership.");
+                    LOGGER.info("Executing is User AUthenticated");
+                    isAuthenticated = keycloakAuthClient.isUserAuthenticated(username, tenantId, accessToken);
+                    //cache the authorization decision
+                    long currentTime = System.currentTimeMillis();
+                    authzCacheManager.addToAuthzCache(new AuthzCacheIndex(username, tenantId, accessToken),
+                            new AuthzCacheEntry(isAuthenticated, currentTime + CACHE_LIFE_TIME, currentTime));
+
+                } else {
+                    //undefined status returned from the authz cache manager
+                    throw new CustosSecurityException("Error in reading from the authorization cache.");
+                }
+            } else {
+                isAuthenticated = keycloakAuthClient.isUserAuthenticated(username, tenantId, accessToken);
+            }
+
+            if (isAuthenticated) {
+                LOGGER.debug("User" + username + "in gateway" + tenantId + "is authenticated");
+
+            } else {
+                LOGGER.debug("User" + username + "in gateway" + tenantId + "is not authenticated");
+            }
+            IsAuthenticateResponse isAuthenticateResponse = IsAuthenticateResponse
+                    .newBuilder()
+                    .setAuthenticated(isAuthenticated)
+                    .build();
+            responseObserver.onNext(isAuthenticateResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while checking authentication for  user " + username + " " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getUserManagementServiceAccountAccessToken(GetUserManagementSATokenRequest request,
+                                                           StreamObserver<AuthToken> responseObserver) {
+        try {
+            LOGGER.debug("Retreiving service account access token for " + request.getClientId());
+            String accessToken = keycloakAuthClient.getUserManagementServiceAccountAccessToken(request.getClientId(),
+                    request.getClientSecret(), String.valueOf(request.getTenantId()));
+
+            AuthToken.Builder builder = AuthToken.newBuilder()
+                    .setAccessToken(accessToken);
+
+
+            Claim userClaim = Claim.newBuilder().setKey("username").setValue(request.getClientId()).build();
+            //  Claim tenantId = Claim.newBuilder().setKey("tenantId").setValue(String.valueOf(request.getTenantId())).build();
+
+            builder.addClaims(userClaim);
+            // builder.addClaims(tenantId);
+
+            AuthToken token = builder.build();
+
+
+            responseObserver.onNext(token);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching access token for  user " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getToken(GetTokenRequest request, StreamObserver<Struct> responseObserver) {
+        try {
+            LOGGER.debug("Request token for " + request.getTenantId());
+
+            JSONObject object = null;
+
+            if (request.getGrantType().equals(Constants.PASSWORD_GRANT_TYPE)) {
+                object = keycloakAuthClient.
+                        getAccessTokenFromPasswordGrantType(request.getClientId(), request.getClientSecret(), String.valueOf(request.getTenantId()),
+                                request.getUsername(), request.getPassword());
+            } else if (request.getGrantType().equals(Constants.REFERESH_TOKEN)) {
+                object = keycloakAuthClient.
+                        getAccessTokenFromRefreshTokenGrantType(request.getClientId(), request.getClientSecret(), String.valueOf(request.getTenantId()),
+                                request.getRefreshToken());
+            } else if (request.getGrantType().equals(Constants.CLIENT_CREDENTIALS)) {
+                object = keycloakAuthClient.getAccessTokenFromClientCredentialsGrantType(request.getClientId(),
+                        request.getClientSecret(), String.valueOf(request.getTenantId()));
+            } else {
+                object = keycloakAuthClient.
+                        getAccessToken(request.getClientId(), request.getClientSecret(), String.valueOf(request.getTenantId()),
+                                request.getCode(), request.getRedirectUri());
+
+            }
+            try {
+                if (object != null && object.getString("access_token") != null) {
+                    Struct.Builder structBuilder = Struct.newBuilder();
+
+                    JsonFormat.parser().merge(object.toString(), structBuilder);
+                    responseObserver.onNext(structBuilder.build());
+                    responseObserver.onCompleted();
+                }
+            } catch (Exception ex) {
+
+                String error = object.getString("error") + " " + object.getString("error_description");
+                responseObserver.onError(Status.INTERNAL.withDescription(error).asRuntimeException());
+                return;
+
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching access token for  user " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getAuthorizeEndpoint(GetAuthorizationEndpointRequest request, StreamObserver<AuthorizationResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request authorization endpoint for " + request.getTenantId());
+
+            String authEndpoint = keycloakAuthClient.getAuthorizationEndpoint(String.valueOf(request.getTenantId()));
+
+            AuthorizationResponse response = AuthorizationResponse.newBuilder().setAuthorizationEndpoint(authEndpoint).build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching access token for  user " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getOIDCConfiguration(GetOIDCConfiguration request, StreamObserver<Struct> responseObserver) {
+        try {
+            LOGGER.debug("Request for fetch OIDC configuration " + request.getTenantId());
+
+
+            JSONObject object = keycloakAuthClient.getOIDCConfiguration(String.valueOf(request.getTenantId()),
+                    request.getClientId());
+
+            Struct.Builder structBuilder = Struct.newBuilder();
+
+            JsonFormat.parser().merge(object.toString(), structBuilder);
+
+            responseObserver.onNext(structBuilder.build());
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching access token for  user " + request.getTenantId() + " " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getTokenByPasswordGrantType(GetTokenRequest request, StreamObserver<Struct> responseObserver) {
+        try {
+            LOGGER.debug("Request token for " + request.getUsername() + " at " + request.getTenantId());
+
+            JSONObject object = keycloakAuthClient.getAccessTokenFromPasswordGrantType(request.getClientId(),
+                    request.getClientSecret(),
+                    String.valueOf(request.getTenantId()),
+                    request.getUsername(),
+                    request.getPassword());
+
+            try {
+                if (object != null && object.getString("access_token") != null) {
+                    Struct.Builder structBuilder = Struct.newBuilder();
+
+                    JsonFormat.parser().merge(object.toString(), structBuilder);
+                    responseObserver.onNext(structBuilder.build());
+                    responseObserver.onCompleted();
+                }
+            } catch (Exception ex) {
+
+                String error = object.getString("error") + " " + object.getString("error_description");
+                responseObserver.onError(Status.INTERNAL.withDescription(error).asRuntimeException());
+                return;
+
+            }
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching access token for  user " + request.getUsername() + " " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getTokenByRefreshTokenGrantType(GetTokenRequest request, StreamObserver<Struct> responseObserver) {
+        try {
+            LOGGER.debug("Request token for " + request.getUsername() + " at " + request.getTenantId());
+
+            JSONObject object = keycloakAuthClient.getAccessTokenFromRefreshTokenGrantType(request.getClientId(),
+                    request.getClientSecret(),
+                    String.valueOf(request.getTenantId()),
+                    request.getRefreshToken());
+
+            try {
+                if (object != null && object.getString("access_token") != null) {
+                    Struct.Builder structBuilder = Struct.newBuilder();
+
+                    JsonFormat.parser().merge(object.toString(), structBuilder);
+                    responseObserver.onNext(structBuilder.build());
+                    responseObserver.onCompleted();
+                }
+            } catch (Exception ex) {
+
+                String error = object.getString("error") + " " + object.getString("error_description");
+                responseObserver.onError(Status.INTERNAL.withDescription(error).asRuntimeException());
+                return;
+
+            }
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching access token for  user " + request.getUsername() + " " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getJWKS(GetJWKSRequest request, StreamObserver<Struct> responseObserver) {
+        try {
+            LOGGER.debug("Request JWT certificates for " + request.getTenantId());
+
+            JSONObject object = keycloakAuthClient.getJWTVerificationCerts(request.getClientId(),
+                    request.getClientSecret(), String.valueOf(request.getTenantId()));
+            try {
+                if (object != null && object.getJSONArray("keys") != null) {
+                    Struct.Builder structBuilder = Struct.newBuilder();
+
+                    JsonFormat.parser().merge(object.toString(), structBuilder);
+                    responseObserver.onNext(structBuilder.build());
+                    responseObserver.onCompleted();
+                }
+            } catch (Exception ex) {
+
+                LOGGER.error("JWKS format  error",ex);
+                String error = object.getString("error") + " " + object.getString("error_description");
+                responseObserver.onError(Status.INTERNAL.withDescription(error).asRuntimeException());
+                return;
+
+            }
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling certs" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void endSession(EndSessionRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request to end session for " + request.getTenantId());
+
+            boolean status = keycloakAuthClient.revokeRefreshToken(request.getClientId(),
+                    request.getClientSecret(), String.valueOf(request.getTenantId()), request.getRefreshToken());
+
+            OperationStatus operationStatus = OperationStatus.newBuilder().setStatus(status).build();
+
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while revoking refresh token" + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+}
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/utils/Constants.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/utils/Constants.java
new file mode 100644
index 0000000..1f2eddc
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/utils/Constants.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.utils;
+
+public class Constants {
+    public static final String PASSWORD_GRANT_TYPE = "password";
+    public static final String CLIENT_CREDENTIALS = "client_credentials";
+    public static final String REFERESH_TOKEN = "refresh_token";
+}
diff --git a/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/validator/InputValidator.java b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/validator/InputValidator.java
new file mode 100644
index 0000000..11b355e
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/java/org/apache/custos/identity/validator/InputValidator.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.validator;
+
+
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.core.services.commons.exceptions.MissingParameterException;
+import org.apache.custos.identity.service.*;
+import org.apache.custos.identity.utils.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class validates the  requests
+ */
+public class InputValidator implements Validator {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "authenticate":
+                validateAuthenticate(obj);
+                break;
+            case "isAuthenticate":
+            case "getUser":
+                validateAuthzToken(obj);
+                break;
+            case "getUserManagementServiceAccountAccessToken":
+                validateGetUserManagementServiceAccountAccessToken(obj);
+                break;
+            case "getToken":
+                validateTokenRequest(obj);
+                break;
+            case "getAuthorizeEndpoint":
+                validateGetAuthorizationEndpoint(obj);
+                break;
+            case "getOIDCConfiguration":
+                validateGetOIDCConfiguration(obj);
+                break;
+            case "getTokenByPasswordGrantType":
+                validatePasswordGrantTypeTokenRequest(obj);
+                break;
+            case "getTokenByRefreshTokenGrantType":
+                validateRefreshGrantTokenRequest(obj);
+                break;
+            case "getJWKS":
+                validateJWKSRequest(obj);
+                break;
+            case "endSession":
+                validateEndSessionRequest(obj);
+                break;
+
+            default:
+                throw new RuntimeException("Method not implemented");
+        }
+
+    }
+
+    private boolean validateAuthenticate(Object obj) {
+        if (obj instanceof AuthenticationRequest) {
+            AuthenticationRequest request = (AuthenticationRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+            if (request.getClientSecret() == null || request.getClientSecret().trim().equals("")) {
+                throw new MissingParameterException("Client secret should not be null", null);
+            }
+            if (request.getUsername() == null || request.getUsername().trim().equals("")) {
+                throw new MissingParameterException("Username should not be null", null);
+            }
+            if (request.getPassword() == null || request.getPassword().trim().equals("")) {
+                throw new MissingParameterException(" password should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method setUPTenant");
+        }
+        return true;
+    }
+
+    private boolean validateAuthzToken(Object obj) {
+        if (obj instanceof AuthToken) {
+            AuthToken request = (AuthToken) obj;
+            String username = null;
+            String tenantId = null;
+
+
+            for (Claim claim : request.getClaimsList()) {
+                LOGGER.info("Key " + claim.getKey() + "Value " + claim.getValue());
+                if (claim.getKey().equals("username")) {
+                    username = claim.getValue();
+                } else if (claim.getKey().equals("tenantId")) {
+                    tenantId = claim.getValue();
+                }
+            }
+            if (request.getAccessToken() == null || request.getAccessToken().trim().equals("")) {
+                throw new MissingParameterException("Access token should not be null", null);
+            }
+
+
+            if (username == null || username.trim().equals("")) {
+                throw new MissingParameterException("Username should not be null", null);
+            }
+
+            if (tenantId == null || tenantId.trim().equals("")) {
+                throw new MissingParameterException("TenantId should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method isUsernameAvailable");
+        }
+        return true;
+    }
+
+
+    private boolean validateGetUserManagementServiceAccountAccessToken(Object obj) {
+        if (obj instanceof GetUserManagementSATokenRequest) {
+            GetUserManagementSATokenRequest request = (GetUserManagementSATokenRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getClientSecret() == null || request.getClientSecret().trim().equals("")) {
+                throw new MissingParameterException("Client secret should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method userAccess");
+        }
+        return true;
+    }
+
+
+    private boolean validateTokenRequest(Object obj) {
+        if (obj instanceof GetTokenRequest) {
+            GetTokenRequest request = (GetTokenRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getClientSecret() == null || request.getClientSecret().trim().equals("")) {
+                throw new MissingParameterException("Client secret should not be null", null);
+            }
+
+            if (request.getGrantType() != null && request.getGrantType().equals(Constants.PASSWORD_GRANT_TYPE)) {
+                if (request.getUsername() == null || request.getUsername().trim().equals("")) {
+                    throw new MissingParameterException("Username should not be null", null);
+                }
+
+                if (request.getPassword() == null || request.getPassword().trim().equals("")) {
+                    throw new MissingParameterException("Password should not be null", null);
+                }
+
+            } else if (request.getGrantType() != null && request.getGrantType().equals(Constants.REFERESH_TOKEN)) {
+                if (request.getRefreshToken() == null || request.getRefreshToken().trim().equals("")) {
+                    throw new MissingParameterException("Refresh token should not be null", null);
+                }
+
+            } else if (request.getGrantType() == null || !request.getGrantType().equals(Constants.CLIENT_CREDENTIALS)) {
+
+                if (request.getRedirectUri() == null || request.getRedirectUri().trim().equals("")) {
+                    throw new MissingParameterException("Redirect Uri should not be null", null);
+                }
+
+                if (request.getCode() == null || request.getCode().trim().equals("")) {
+                    throw new MissingParameterException("code should not be null", null);
+                }
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method userAccess");
+        }
+        return true;
+    }
+
+
+    private boolean validatePasswordGrantTypeTokenRequest(Object obj) {
+        if (obj instanceof GetTokenRequest) {
+            GetTokenRequest request = (GetTokenRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getClientSecret() == null || request.getClientSecret().trim().equals("")) {
+                throw new MissingParameterException("Client secret should not be null", null);
+            }
+            if (request.getUsername() == null || request.getUsername().trim().equals("")) {
+                throw new MissingParameterException("Username should not be null", null);
+            }
+
+            if (request.getPassword() == null || request.getPassword().trim().equals("")) {
+                throw new MissingParameterException("Password should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method getTokenByPasswordGrantType");
+        }
+        return true;
+    }
+
+
+    private boolean validateRefreshGrantTokenRequest(Object obj) {
+        if (obj instanceof GetTokenRequest) {
+            GetTokenRequest request = (GetTokenRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getClientSecret() == null || request.getClientSecret().trim().equals("")) {
+                throw new MissingParameterException("Client secret should not be null", null);
+            }
+            if (request.getRefreshToken() == null || request.getRefreshToken().trim().equals("")) {
+                throw new MissingParameterException("Refresh token should not be null", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method getTokenByRefreshTokenGrantType");
+        }
+        return true;
+    }
+
+    private boolean validateGetAuthorizationEndpoint(Object obj) {
+        if (obj instanceof GetAuthorizationEndpointRequest) {
+            GetAuthorizationEndpointRequest request = (GetAuthorizationEndpointRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateGetAuthorizationEndpoint");
+        }
+        return true;
+    }
+
+    private boolean validateGetOIDCConfiguration(Object obj) {
+        if (obj instanceof GetOIDCConfiguration) {
+            GetOIDCConfiguration request = (GetOIDCConfiguration) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method validateGetOIDCConfiguration");
+        }
+        return true;
+    }
+
+    private boolean validateJWKSRequest(Object obj) {
+        if (obj instanceof GetJWKSRequest) {
+            GetJWKSRequest request = (GetJWKSRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getClientSecret() == null || request.getClientSecret().trim().equals("")) {
+                throw new MissingParameterException("Client secret should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method getTokenByRefreshTokenGrantType");
+        }
+        return true;
+    }
+
+
+    private boolean validateEndSessionRequest(Object obj) {
+        if (obj instanceof EndSessionRequest) {
+            EndSessionRequest request = (EndSessionRequest) obj;
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("Client Id should not be null", null);
+            }
+
+            if (request.getClientSecret() == null || request.getClientSecret().trim().equals("")) {
+                throw new MissingParameterException("Client secret should not be null", null);
+            }
+
+            if (request.getRefreshToken() == null || request.getRefreshToken().trim().equals("")) {
+                throw new MissingParameterException("Refresh token should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method getTokenByRefreshTokenGrantType");
+        }
+        return true;
+    }
+}
diff --git a/custos-core-services/identity-core-service/src/main/proto/IdentityService.proto b/custos-core-services/identity-core-service/src/main/proto/IdentityService.proto
new file mode 100644
index 0000000..c6108d9
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/proto/IdentityService.proto
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.identity.service;
+import "google/protobuf/struct.proto";
+
+
+message AuthToken {
+    string access_token = 1;
+    repeated Claim claims = 2;
+}
+
+
+message Claim {
+    string key = 1;
+    string value = 2;
+}
+
+message User {
+    string sub = 1;
+    string fullName = 2;
+    string firstName = 3;
+    string lastName = 4;
+    string emailAddress = 5;
+    string username = 6;
+}
+
+
+message GetTokenRequest {
+    int64 tenant_id = 1;
+    string client_id = 2;
+    string client_secret = 3;
+    string redirect_uri = 4;
+    string code = 6;
+    string username = 7;
+    string password = 8;
+    string refresh_token = 9;
+    string grant_type = 10;
+}
+
+message TokenResponse {
+    string access_token = 1;
+    double expires_in = 2;
+    double refresh_expires_in = 3;
+    string refresh_token = 4;
+    string token_type = 5;
+    string id_token = 6;
+    double not_before_policy = 7;
+    string session_state = 8;
+    string scope = 9;
+}
+
+
+message AuthenticationRequest {
+    string clientId = 1;
+    string clientSecret = 2;
+    int64 tenantId = 3;
+    string username = 4;
+    string password = 5;
+}
+
+message IsAuthenticateResponse {
+    bool authenticated = 1;
+}
+
+message GetUserManagementSATokenRequest {
+    string clientId = 1;
+    string clientSecret = 2;
+    int64 tenantId = 3;
+}
+
+message GetAuthorizationEndpointRequest {
+    int64 tenantId = 1;
+}
+
+message AuthorizationResponse {
+    string authorizationEndpoint = 2;
+}
+
+message GetOIDCConfiguration {
+    string client_id = 1;
+    string client_secret = 2;
+    int64 tenant_id = 3;
+}
+
+message GetJWKSRequest {
+    string client_id = 1;
+    string client_secret = 2;
+    int64 tenant_id = 3;
+}
+
+message EndSessionRequest {
+    string client_id = 1;
+    string client_secret = 2;
+    int64 tenant_id = 3;
+    string refresh_token = 4;
+}
+
+message OperationStatus {
+    bool status = 1;
+}
+
+service IdentityService {
+    rpc authenticate (AuthenticationRequest) returns (AuthToken);
+    rpc isAuthenticate (AuthToken) returns (IsAuthenticateResponse);
+    rpc getUser (AuthToken) returns (User);
+    rpc getUserManagementServiceAccountAccessToken (GetUserManagementSATokenRequest) returns (AuthToken);
+    rpc getToken (GetTokenRequest) returns (google.protobuf.Struct);
+    rpc getAuthorizeEndpoint (GetAuthorizationEndpointRequest) returns (AuthorizationResponse);
+    rpc getOIDCConfiguration (GetOIDCConfiguration) returns (google.protobuf.Struct);
+    rpc getTokenByPasswordGrantType (GetTokenRequest) returns (google.protobuf.Struct);
+    rpc getTokenByRefreshTokenGrantType (GetTokenRequest) returns (google.protobuf.Struct);
+    rpc getJWKS (GetJWKSRequest) returns (google.protobuf.Struct);
+    rpc endSession(EndSessionRequest) returns (OperationStatus);
+
+}
\ No newline at end of file
diff --git a/custos-core-services/identity-core-service/src/main/proto/IdentityService_pb.js b/custos-core-services/identity-core-service/src/main/proto/IdentityService_pb.js
new file mode 100644
index 0000000..6a93898
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/proto/IdentityService_pb.js
@@ -0,0 +1,3255 @@
+// source: src/main/proto/IdentityService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+var google_protobuf_struct_pb = require('google-protobuf/google/protobuf/struct_pb.js');
+goog.object.extend(proto, google_protobuf_struct_pb);
+goog.exportSymbol('proto.org.apache.custos.identity.service.AuthToken', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.AuthenticationRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.AuthorizationResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.Claim', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.EndSessionRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetJWKSRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetOIDCConfiguration', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetTokenRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.IsAuthenticateResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.OperationStatus', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.TokenResponse', null, global);
+goog.exportSymbol('proto.org.apache.custos.identity.service.User', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.AuthToken = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.identity.service.AuthToken.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.AuthToken, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.AuthToken.displayName = 'proto.org.apache.custos.identity.service.AuthToken';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.Claim = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.Claim, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.Claim.displayName = 'proto.org.apache.custos.identity.service.Claim';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.User = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.User, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.User.displayName = 'proto.org.apache.custos.identity.service.User';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetTokenRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetTokenRequest.displayName = 'proto.org.apache.custos.identity.service.GetTokenRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.TokenResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.TokenResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.TokenResponse.displayName = 'proto.org.apache.custos.identity.service.TokenResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.AuthenticationRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.AuthenticationRequest.displayName = 'proto.org.apache.custos.identity.service.AuthenticationRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.IsAuthenticateResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.IsAuthenticateResponse.displayName = 'proto.org.apache.custos.identity.service.IsAuthenticateResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.displayName = 'proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.displayName = 'proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.AuthorizationResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.AuthorizationResponse.displayName = 'proto.org.apache.custos.identity.service.AuthorizationResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetOIDCConfiguration, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetOIDCConfiguration.displayName = 'proto.org.apache.custos.identity.service.GetOIDCConfiguration';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.GetJWKSRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.GetJWKSRequest.displayName = 'proto.org.apache.custos.identity.service.GetJWKSRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.EndSessionRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.EndSessionRequest.displayName = 'proto.org.apache.custos.identity.service.EndSessionRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.identity.service.OperationStatus = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.identity.service.OperationStatus, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.identity.service.OperationStatus.displayName = 'proto.org.apache.custos.identity.service.OperationStatus';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.identity.service.AuthToken.repeatedFields_ = [2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.AuthToken.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthToken.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    claimsList: jspb.Message.toObjectList(msg.getClaimsList(),
+    proto.org.apache.custos.identity.service.Claim.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.AuthToken}
+ */
+proto.org.apache.custos.identity.service.AuthToken.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.AuthToken;
+  return proto.org.apache.custos.identity.service.AuthToken.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.AuthToken}
+ */
+proto.org.apache.custos.identity.service.AuthToken.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 2:
+      var value = new proto.org.apache.custos.identity.service.Claim;
+      reader.readMessage(value,proto.org.apache.custos.identity.service.Claim.deserializeBinaryFromReader);
+      msg.addClaims(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.AuthToken.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.AuthToken} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthToken.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClaimsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.org.apache.custos.identity.service.Claim.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string accessToken = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthToken} returns this
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * repeated Claim claims = 2;
+ * @return {!Array<!proto.org.apache.custos.identity.service.Claim>}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.getClaimsList = function() {
+  return /** @type{!Array<!proto.org.apache.custos.identity.service.Claim>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.org.apache.custos.identity.service.Claim, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.org.apache.custos.identity.service.Claim>} value
+ * @return {!proto.org.apache.custos.identity.service.AuthToken} returns this
+*/
+proto.org.apache.custos.identity.service.AuthToken.prototype.setClaimsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.org.apache.custos.identity.service.Claim=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.identity.service.Claim}
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.addClaims = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.org.apache.custos.identity.service.Claim, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.identity.service.AuthToken} returns this
+ */
+proto.org.apache.custos.identity.service.AuthToken.prototype.clearClaimsList = function() {
+  return this.setClaimsList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.Claim.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.Claim} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.Claim.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    key: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    value: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.Claim}
+ */
+proto.org.apache.custos.identity.service.Claim.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.Claim;
+  return proto.org.apache.custos.identity.service.Claim.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.Claim} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.Claim}
+ */
+proto.org.apache.custos.identity.service.Claim.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setKey(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.Claim.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.Claim} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.Claim.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKey();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getValue();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string key = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.getKey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.Claim} returns this
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.setKey = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string value = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.getValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.Claim} returns this
+ */
+proto.org.apache.custos.identity.service.Claim.prototype.setValue = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.User.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.User.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.User} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.User.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    sub: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    fullname: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    firstname: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    lastname: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    emailaddress: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.User}
+ */
+proto.org.apache.custos.identity.service.User.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.User;
+  return proto.org.apache.custos.identity.service.User.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.User} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.User}
+ */
+proto.org.apache.custos.identity.service.User.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSub(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFullname(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFirstname(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLastname(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEmailaddress(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.User.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.User.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.User} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.User.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSub();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getFullname();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getFirstname();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getLastname();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getEmailaddress();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string sub = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getSub = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setSub = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string fullName = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getFullname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setFullname = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string firstName = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getFirstname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setFirstname = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string lastName = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getLastname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setLastname = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string emailAddress = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getEmailaddress = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setEmailaddress = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string username = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.User.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.User} returns this
+ */
+proto.org.apache.custos.identity.service.User.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetTokenRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    clientId: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    redirectUri: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    code: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    password: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    refreshToken: jspb.Message.getFieldWithDefault(msg, 9, ""),
+    grantType: jspb.Message.getFieldWithDefault(msg, 10, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetTokenRequest;
+  return proto.org.apache.custos.identity.service.GetTokenRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRedirectUri(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCode(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRefreshToken(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGrantType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetTokenRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetTokenRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getRedirectUri();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getCode();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getRefreshToken();
+  if (f.length > 0) {
+    writer.writeString(
+      9,
+      f
+    );
+  }
+  f = message.getGrantType();
+  if (f.length > 0) {
+    writer.writeString(
+      10,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenant_id = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string client_id = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string client_secret = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string redirect_uri = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getRedirectUri = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setRedirectUri = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string code = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getCode = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setCode = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string username = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string password = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional string refresh_token = 9;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getRefreshToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setRefreshToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 9, value);
+};
+
+
+/**
+ * optional string grant_type = 10;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.getGrantType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 10, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetTokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetTokenRequest.prototype.setGrantType = function(value) {
+  return jspb.Message.setProto3StringField(this, 10, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.TokenResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.TokenResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.TokenResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    accessToken: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    expiresIn: jspb.Message.getFloatingPointFieldWithDefault(msg, 2, 0.0),
+    refreshExpiresIn: jspb.Message.getFloatingPointFieldWithDefault(msg, 3, 0.0),
+    refreshToken: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    tokenType: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    idToken: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    notBeforePolicy: jspb.Message.getFloatingPointFieldWithDefault(msg, 7, 0.0),
+    sessionState: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    scope: jspb.Message.getFieldWithDefault(msg, 9, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.TokenResponse;
+  return proto.org.apache.custos.identity.service.TokenResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.TokenResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccessToken(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setExpiresIn(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setRefreshExpiresIn(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRefreshToken(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTokenType(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIdToken(value);
+      break;
+    case 7:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setNotBeforePolicy(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSessionState(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setScope(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.TokenResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.TokenResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.TokenResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAccessToken();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getExpiresIn();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      2,
+      f
+    );
+  }
+  f = message.getRefreshExpiresIn();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      3,
+      f
+    );
+  }
+  f = message.getRefreshToken();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getTokenType();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getIdToken();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getNotBeforePolicy();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      7,
+      f
+    );
+  }
+  f = message.getSessionState();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = message.getScope();
+  if (f.length > 0) {
+    writer.writeString(
+      9,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string access_token = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getAccessToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setAccessToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional double expires_in = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getExpiresIn = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 2, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setExpiresIn = function(value) {
+  return jspb.Message.setProto3FloatField(this, 2, value);
+};
+
+
+/**
+ * optional double refresh_expires_in = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getRefreshExpiresIn = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 3, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setRefreshExpiresIn = function(value) {
+  return jspb.Message.setProto3FloatField(this, 3, value);
+};
+
+
+/**
+ * optional string refresh_token = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getRefreshToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setRefreshToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string token_type = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getTokenType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setTokenType = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string id_token = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getIdToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setIdToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional double not_before_policy = 7;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getNotBeforePolicy = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 7, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setNotBeforePolicy = function(value) {
+  return jspb.Message.setProto3FloatField(this, 7, value);
+};
+
+
+/**
+ * optional string session_state = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getSessionState = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setSessionState = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * optional string scope = 9;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.getScope = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.TokenResponse} returns this
+ */
+proto.org.apache.custos.identity.service.TokenResponse.prototype.setScope = function(value) {
+  return jspb.Message.setProto3StringField(this, 9, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.AuthenticationRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    username: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    password: jspb.Message.getFieldWithDefault(msg, 5, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.AuthenticationRequest;
+  return proto.org.apache.custos.identity.service.AuthenticationRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.AuthenticationRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.AuthenticationRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string clientId = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string clientSecret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenantId = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string username = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string password = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthenticationRequest} returns this
+ */
+proto.org.apache.custos.identity.service.AuthenticationRequest.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.IsAuthenticateResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.IsAuthenticateResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    authenticated: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.IsAuthenticateResponse}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.IsAuthenticateResponse;
+  return proto.org.apache.custos.identity.service.IsAuthenticateResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.IsAuthenticateResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.IsAuthenticateResponse}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAuthenticated(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.IsAuthenticateResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.IsAuthenticateResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAuthenticated();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool authenticated = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.prototype.getAuthenticated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.identity.service.IsAuthenticateResponse} returns this
+ */
+proto.org.apache.custos.identity.service.IsAuthenticateResponse.prototype.setAuthenticated = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest;
+  return proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string clientId = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string clientSecret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenantId = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetUserManagementSATokenRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest;
+  return proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetAuthorizationEndpointRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.AuthorizationResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.AuthorizationResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    authorizationendpoint: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.AuthorizationResponse}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.AuthorizationResponse;
+  return proto.org.apache.custos.identity.service.AuthorizationResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.AuthorizationResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.AuthorizationResponse}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAuthorizationendpoint(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.AuthorizationResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.AuthorizationResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAuthorizationendpoint();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string authorizationEndpoint = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.prototype.getAuthorizationendpoint = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.AuthorizationResponse} returns this
+ */
+proto.org.apache.custos.identity.service.AuthorizationResponse.prototype.setAuthorizationendpoint = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetOIDCConfiguration.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetOIDCConfiguration;
+  return proto.org.apache.custos.identity.service.GetOIDCConfiguration.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetOIDCConfiguration.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} returns this
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string client_secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} returns this
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetOIDCConfiguration} returns this
+ */
+proto.org.apache.custos.identity.service.GetOIDCConfiguration.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.GetJWKSRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.GetJWKSRequest;
+  return proto.org.apache.custos.identity.service.GetJWKSRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.GetJWKSRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.GetJWKSRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string client_secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.GetJWKSRequest} returns this
+ */
+proto.org.apache.custos.identity.service.GetJWKSRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.EndSessionRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.EndSessionRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    clientId: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    clientSecret: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantId: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    refreshToken: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.EndSessionRequest;
+  return proto.org.apache.custos.identity.service.EndSessionRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.EndSessionRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientSecret(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantId(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRefreshToken(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.EndSessionRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.EndSessionRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getClientId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getClientSecret();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantId();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getRefreshToken();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string client_id = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.getClientId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.setClientId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string client_secret = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.getClientSecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.setClientSecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenant_id = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.getTenantId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.setTenantId = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string refresh_token = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.getRefreshToken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.identity.service.EndSessionRequest} returns this
+ */
+proto.org.apache.custos.identity.service.EndSessionRequest.prototype.setRefreshToken = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.identity.service.OperationStatus.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.identity.service.OperationStatus} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.OperationStatus.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    status: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.identity.service.OperationStatus}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.identity.service.OperationStatus;
+  return proto.org.apache.custos.identity.service.OperationStatus.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.identity.service.OperationStatus} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.identity.service.OperationStatus}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setStatus(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.identity.service.OperationStatus.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.identity.service.OperationStatus} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.identity.service.OperationStatus.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getStatus();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool status = 1;
+ * @return {boolean}
+ */
+proto.org.apache.custos.identity.service.OperationStatus.prototype.getStatus = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.org.apache.custos.identity.service.OperationStatus} returns this
+ */
+proto.org.apache.custos.identity.service.OperationStatus.prototype.setStatus = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+goog.object.extend(exports, proto.org.apache.custos.identity.service);
diff --git a/custos-core-services/identity-core-service/src/main/resources/application.properties b/custos-core-services/identity-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..27e8f36
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/resources/application.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=identityCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_identity?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
\ No newline at end of file
diff --git a/custos-core-services/identity-core-service/src/main/resources/bootstrap.properties b/custos-core-services/identity-core-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..760bf92
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+spring.profiles.active:default
\ No newline at end of file
diff --git a/custos-core-services/identity-core-service/src/main/resources/keycloak-client-truststore.pkcs12 b/custos-core-services/identity-core-service/src/main/resources/keycloak-client-truststore.pkcs12
new file mode 100644
index 0000000..9d74713
--- /dev/null
+++ b/custos-core-services/identity-core-service/src/main/resources/keycloak-client-truststore.pkcs12
Binary files differ
diff --git a/custos-core-services/pom.xml b/custos-core-services/pom.xml
new file mode 100644
index 0000000..d7f4134
--- /dev/null
+++ b/custos-core-services/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-core-services</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>tenant-profile-core-service</module>
+        <module>utility-services/custos-configuration-service</module>
+        <module>iam-admin-core-service</module>
+        <module>credential-store-core-service</module>
+        <module>federated-authentication-core-service</module>
+        <module>custos-core-services-commons</module>
+        <module>identity-core-service</module>
+        <module>user-profile-core-service</module>
+        <module>agent-profile-core-service</module>
+        <module>cluster-management-core-service</module>
+        <module>resource-secret-core-service</module>
+        <module>sharing-core-service</module>
+        <module>custos-logging</module>
+    </modules>
+
+
+
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/resource-secret-core-service/Dockerfile b/custos-core-services/resource-secret-core-service/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/resource-secret-core-service/pom.xml b/custos-core-services/resource-secret-core-service/pom.xml
new file mode 100644
index 0000000..2d7ccaf
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/pom.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>resource-secret-core-service</artifactId>
+    <dependencies>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-vault-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.jcraft</groupId>
+            <artifactId>jsch</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/.helmignore b/custos-core-services/resource-secret-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/Chart.yaml b/custos-core-services/resource-secret-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..a5ed0ec
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of resource secret core service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/resource-secret-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/resource-secret-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/resource-secret-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..31e54a6
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,64 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/resource-secret-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/templates/service.yaml b/custos-core-services/resource-secret-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/resource-secret-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/resource-secret-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/resource-secret-core-service/src/main/helm/values.yaml b/custos-core-services/resource-secret-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..fa8b2ef
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/helm/values.yaml
@@ -0,0 +1,79 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/ResourceSecretServiceInitializer.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/ResourceSecretServiceInitializer.java
new file mode 100644
index 0000000..5f8ef6c
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/ResourceSecretServiceInitializer.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret;
+
+import io.grpc.ServerInterceptor;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableJpaRepositories(basePackages = "org.apache.custos")
+@ComponentScan(basePackages = "org.apache.custos")
+@EntityScan(basePackages = "org.apache.custos")
+public class ResourceSecretServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(ResourceSecretServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/exceptions/CredentialStoreException.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/exceptions/CredentialStoreException.java
new file mode 100644
index 0000000..645cf15
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/exceptions/CredentialStoreException.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.exceptions;
+
+public class CredentialStoreException extends RuntimeException {
+    public CredentialStoreException(String s, Exception exception) {
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/Credential.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/Credential.java
new file mode 100644
index 0000000..1bb80d2
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/Credential.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.manager;
+
+/**
+ * Common interface for Resource Secrets
+ */
+public interface Credential {
+
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/CredentialGeneratorFactory.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/CredentialGeneratorFactory.java
new file mode 100644
index 0000000..5d13bee
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/CredentialGeneratorFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.manager;
+
+import com.google.protobuf.GeneratedMessageV3;
+import org.apache.custos.resource.secret.service.CertificateCredential;
+import org.apache.custos.resource.secret.service.PasswordCredential;
+import org.apache.custos.resource.secret.service.SSHCredential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class is responsible for generate secrets
+ */
+@Component
+public class CredentialGeneratorFactory {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CredentialGeneratorFactory.class);
+
+
+    public Credential getCredential(GeneratedMessageV3 message) throws Exception {
+
+        if (message instanceof SSHCredential) {
+            return new org.apache.custos.resource.secret.manager.adaptor.outbound.SSHCredential(message);
+        } else if (message instanceof CertificateCredential) {
+            return new org.apache.custos.resource.secret.manager.adaptor.outbound.CertificateCredential(message);
+        } else if (message instanceof PasswordCredential) {
+            return new org.apache.custos.resource.secret.manager.adaptor.outbound.PasswordCredential(message);
+        }
+
+        return null;
+    }
+
+
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/inbound/CredentialReader.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/inbound/CredentialReader.java
new file mode 100644
index 0000000..f0eba2c
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/inbound/CredentialReader.java
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.manager.adaptor.inbound;
+
+import org.apache.custos.resource.secret.service.*;
+import org.apache.custos.resource.secret.utils.Constants;
+import org.apache.custos.resource.secret.manager.adaptor.outbound.CredentialWriter;
+import org.apache.custos.resource.secret.persistance.local.model.Secret;
+import org.apache.custos.resource.secret.persistance.local.repository.SecretRepository;
+import org.apache.custos.resource.secret.persistance.vault.Certificate;
+import org.apache.custos.resource.secret.persistance.vault.PasswordSecret;
+import org.apache.custos.resource.secret.persistance.vault.SSHCredentialSecrets;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.vault.core.VaultTemplate;
+import org.springframework.vault.support.VaultResponseSupport;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@Component
+public class CredentialReader {
+
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CredentialWriter.class);
+
+    @Autowired
+    private SecretRepository repository;
+
+    @Autowired
+    private VaultTemplate vaultTemplate;
+
+
+    /**
+     * get SSH credentials
+     *
+     * @param tenantId
+     * @param token
+     * @return
+     */
+    public SSHCredential getSSHCredential(long tenantId, String token) {
+
+        Optional<Secret> secret = repository.findById(token);
+
+
+        if (secret.isEmpty()) {
+            return null;
+        }
+
+        Secret exSec = secret.get();
+
+        String vaultPath = Constants.VAULT_RESOURCE_SECRETS_PATH + tenantId + "/" + exSec.getOwnerId() +
+                "/" + Constants.SSH_CREDENTIALS + "/" + token;
+
+
+        VaultResponseSupport<SSHCredentialSecrets> response = vaultTemplate.read(vaultPath, SSHCredentialSecrets.class);
+
+        if (response == null || response.getData() == null && response.getData().getPrivateKey() == null) {
+            repository.delete(exSec);
+            return null;
+        }
+
+        SSHCredentialSecrets sshCredentialSecrets = response.getData();
+
+        SecretMetadata metadata = SecretMetadata.newBuilder()
+                .setOwnerId(exSec.getOwnerId())
+                .setTenantId(tenantId)
+                .setPersistedTime(exSec.getCreatedAt().getTime())
+                .setDescription(exSec.getDiscription())
+                .setResourceType(ResourceType.VAULT_CREDENTIAL)
+                .setSource(ResourceSource.EXTERNAL)
+                .setToken(token)
+                .build();
+
+        SSHCredential credential = SSHCredential.newBuilder()
+                .setPassphrase(sshCredentialSecrets.getPassphrase())
+                .setPrivateKey(sshCredentialSecrets.getPrivateKey())
+                .setPublicKey(sshCredentialSecrets.getPublicKey())
+                .setMetadata(metadata)
+                .build();
+
+        return credential;
+
+    }
+
+
+    /**
+     * get password credential
+     *
+     * @param tenantId
+     * @param token
+     * @return
+     */
+    public org.apache.custos.resource.secret.service.PasswordCredential getPasswordCredential(long tenantId, String token) {
+        Optional<Secret> secret = repository.findById(token);
+
+
+        if (secret.isEmpty()) {
+            return null;
+        }
+
+        Secret exSec = secret.get();
+
+        String vaultPath = Constants.VAULT_RESOURCE_SECRETS_PATH + tenantId + "/" + exSec.getOwnerId() +
+                "/" + Constants.PASSWORD + "/" + token;
+
+
+        VaultResponseSupport<PasswordSecret> response = vaultTemplate.read(vaultPath, PasswordSecret.class);
+
+        if (response == null || response.getData() == null && response.getData().getPassword() == null) {
+            repository.delete(exSec);
+            return null;
+        }
+
+        PasswordSecret passwordSecret = response.getData();
+
+        SecretMetadata metadata = SecretMetadata.newBuilder()
+                .setOwnerId(exSec.getOwnerId())
+                .setTenantId(tenantId)
+                .setPersistedTime(exSec.getCreatedAt().getTime())
+                .setDescription(exSec.getDiscription())
+                .setResourceType(ResourceType.VAULT_CREDENTIAL)
+                .setSource(ResourceSource.EXTERNAL)
+                .setToken(token)
+                .build();
+
+        org.apache.custos.resource.secret.service.PasswordCredential credential =
+                org.apache.custos.resource.secret.service.PasswordCredential.newBuilder()
+                        .setPassword(passwordSecret.getPassword())
+                        .setMetadata(metadata)
+                        .build();
+
+        return credential;
+
+
+    }
+
+    /**
+     * get certificate credential
+     *
+     * @param tenantId
+     * @param token
+     * @return
+     */
+    public CertificateCredential getCertificateCredential(long tenantId, String token) {
+        Optional<Secret> secret = repository.findById(token);
+
+        if (secret.isEmpty()) {
+            return null;
+        }
+
+        Secret exSec = secret.get();
+
+        String vaultPath = Constants.VAULT_RESOURCE_SECRETS_PATH + tenantId + "/" + exSec.getOwnerId() +
+                "/" + Constants.PASSWORD + "/" + token;
+
+        VaultResponseSupport<Certificate> response = vaultTemplate.read(vaultPath, Certificate.class);
+
+        if (response == null || response.getData() == null && response.getData().getCertificate() == null) {
+            repository.delete(exSec);
+            return null;
+        }
+
+        Certificate certificate = response.getData();
+
+        SecretMetadata metadata = SecretMetadata.newBuilder()
+                .setOwnerId(exSec.getOwnerId())
+                .setTenantId(tenantId)
+                .setPersistedTime(exSec.getCreatedAt().getTime())
+                .setDescription(exSec.getDiscription())
+                .setResourceType(ResourceType.VAULT_CREDENTIAL)
+                .setSource(ResourceSource.EXTERNAL)
+                .setToken(token)
+                .build();
+
+        CertificateCredential certificateCredential = CertificateCredential.newBuilder()
+                .setLifeTime(Long.valueOf(certificate.getLifetime()))
+                .setNotAfter(certificate.getNotAfter())
+                .setNotBefore(certificate.getNotBefore())
+                .setPrivateKey(certificate.getPrivateKey())
+                .setX509Cert(certificate.getCertificate())
+                .setMetadata(metadata)
+                .build();
+
+        return certificateCredential;
+
+    }
+
+    /**
+     * Get credential summary
+     *
+     * @param tenantId
+     * @param token
+     * @return
+     */
+    public SecretMetadata getCredentialSummary(long tenantId, String token) {
+
+        Optional<Secret> exSec = repository.findById(token);
+
+        if (exSec.isEmpty()) {
+            return null;
+        }
+
+        Secret secret = exSec.get();
+
+        return SecretMetadata.newBuilder()
+                .setToken(token)
+                .setTenantId(tenantId)
+                .setDescription(secret.getDiscription())
+                .setPersistedTime(secret.getCreatedAt().getTime())
+                .setType(ResourceSecretType.valueOf(secret.getSecretType()))
+                .setResourceType(ResourceType.VAULT_CREDENTIAL)
+                .setSource(ResourceSource.EXTERNAL)
+                .setOwnerId(secret.getOwnerId())
+                .build();
+
+    }
+
+    /**
+     * get All credential summaries
+     *
+     * @param tenantId
+     * @param tokens
+     * @return
+     */
+    public List<SecretMetadata> getAllCredentialSummaries(long tenantId, List<String> tokens) {
+
+        List<Secret> secrets = repository.findAllById(tokens);
+        List<SecretMetadata> metadata = new ArrayList<>();
+
+        if (secrets != null && !secrets.isEmpty()) {
+
+
+            secrets.forEach(secret -> {
+                metadata.add(SecretMetadata.newBuilder()
+                        .setToken(secret.getId())
+                        .setTenantId(tenantId)
+                        .setDescription(secret.getDiscription())
+                        .setPersistedTime(secret.getCreatedAt().getTime())
+                        .setType(ResourceSecretType.valueOf(secret.getSecretType()))
+                        .setResourceType(ResourceType.VAULT_CREDENTIAL)
+                        .setSource(ResourceSource.EXTERNAL)
+                        .setOwnerId(secret.getOwnerId())
+                        .build());
+            });
+
+
+        }
+
+        return metadata;
+
+    }
+
+
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/CertificateCredential.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/CertificateCredential.java
new file mode 100644
index 0000000..d52d677
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/CertificateCredential.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.manager.adaptor.outbound;
+
+import com.google.protobuf.GeneratedMessageV3;
+import org.apache.commons.codec.binary.Base64;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+/**
+ * This class creates CertificateCredential from gRPC CertificateCredential
+ */
+public class CertificateCredential extends ResourceCredential {
+
+    private X509Certificate certificate;
+
+    private String cert;
+
+    private long lifetime;
+
+    private String notBefore;
+
+    private String notAfter;
+
+    private String privateKey;
+
+
+    public CertificateCredential(GeneratedMessageV3 message) throws CertificateException {
+        super(message);
+        if (message instanceof org.apache.custos.resource.secret.service.CertificateCredential) {
+            this.privateKey = ((org.apache.custos.resource.secret.service.CertificateCredential) message).getPrivateKey();
+            String certi = ((org.apache.custos.resource.secret.service.CertificateCredential) message).getX509Cert();
+            Base64 encoder = new Base64(64);
+            byte[] decoded = encoder.decode(certi.replaceAll("-----BEGIN CERTIFICATE-----", "").replaceAll("-----END CERTIFICATE-----", ""));
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            this.certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(decoded));
+            this.notAfter = this.certificate.getNotAfter().toString();
+            this.notBefore = this.certificate.getNotBefore().toString();
+            this.lifetime = this.certificate.getNotAfter().getTime() - this.certificate.getNotBefore().getTime();
+            this.cert = this.certificate.toString();
+        }
+    }
+
+    public X509Certificate getCertificate() {
+        return certificate;
+    }
+
+
+    public void setCertificate(X509Certificate certificate) {
+        this.certificate = certificate;
+    }
+
+    public String getCert() {
+        return cert;
+    }
+
+    public void setCert(String cert) {
+        this.cert = cert;
+    }
+
+    public long getLifetime() {
+        return lifetime;
+    }
+
+    public void setLifetime(long lifetime) {
+        this.lifetime = lifetime;
+    }
+
+    public String getNotBefore() {
+        return notBefore;
+    }
+
+    public void setNotBefore(String notBefore) {
+        this.notBefore = notBefore;
+    }
+
+    public String getNotAfter() {
+        return notAfter;
+    }
+
+    public void setNotAfter(String notAfter) {
+        this.notAfter = notAfter;
+    }
+
+    public String getPrivateKey() {
+        return privateKey;
+    }
+
+    public void setPrivateKey(String privateKey) {
+        this.privateKey = privateKey;
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/CredentialWriter.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/CredentialWriter.java
new file mode 100644
index 0000000..edbb241
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/CredentialWriter.java
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.manager.adaptor.outbound;
+
+import org.apache.custos.resource.secret.utils.Constants;
+import org.apache.custos.resource.secret.exceptions.CredentialStoreException;
+import org.apache.custos.resource.secret.persistance.local.model.Secret;
+import org.apache.custos.resource.secret.persistance.local.repository.SecretRepository;
+import org.apache.custos.resource.secret.persistance.vault.Certificate;
+import org.apache.custos.resource.secret.persistance.vault.PasswordSecret;
+import org.apache.custos.resource.secret.persistance.vault.SSHCredentialSecrets;
+import org.apache.custos.resource.secret.service.ResourceSecretType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.vault.core.VaultTemplate;
+import org.springframework.vault.support.VaultResponseSupport;
+
+import java.util.Optional;
+
+/**
+ * This class received gPRC credentials
+ */
+@Component
+public class CredentialWriter {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CredentialWriter.class);
+
+    @Autowired
+    private SecretRepository repository;
+
+    @Autowired
+    private VaultTemplate vaultTemplate;
+
+    /**
+     * Save SSHCredential in database
+     *
+     * @param credential
+     * @return
+     */
+    public boolean saveSSHCredential(SSHCredential credential) {
+
+        Optional<Secret> exSecret = repository.findById(credential.getToken());
+
+        if (exSecret.isPresent()) {
+            String msg = " Credential with token " + credential.getToken() + " already exist";
+            LOGGER.error(msg);
+            throw new CredentialStoreException(msg, null);
+        }
+
+        String path = Constants.VAULT_RESOURCE_SECRETS_PATH + credential.getTenantId() + "/" + credential.getOwnerId()
+                + "/" + Constants.SSH_CREDENTIALS + "/" + credential.getToken();
+
+
+        SSHCredentialSecrets sshCredentialSecrets = new SSHCredentialSecrets
+                (credential.getPrivateKey(), credential.getPublicKey(), credential.getPassPhrase());
+        vaultTemplate.write(path, sshCredentialSecrets);
+
+        VaultResponseSupport<SSHCredentialSecrets> response = vaultTemplate.read(path, SSHCredentialSecrets.class);
+
+        if (response == null || response.getData() == null && response.getData().getPrivateKey() == null) {
+            String msg = " SSH credential of tenant " + credential.getTenantId() +
+                    " of user " + credential.getOwnerId() + " is not saved in vault";
+            LOGGER.error(msg);
+            throw new CredentialStoreException(msg, null);
+        }
+
+        Secret secret = new Secret();
+        secret.setId(credential.getToken());
+        secret.setDiscription(credential.getDescription());
+        secret.setOwnerId(credential.getOwnerId());
+        secret.setOwnerType(credential.getResourceOwnerType().name());
+        secret.setSecretType(ResourceSecretType.SSH.name());
+        secret.setTenantId(credential.getTenantId());
+        repository.save(secret);
+        return true;
+    }
+
+    /**
+     * save Password credential in Vault and DB
+     *
+     * @param credential
+     * @return
+     */
+    public boolean savePasswordCredential(PasswordCredential credential) {
+        Optional<Secret> exSecret = repository.findById(credential.getToken());
+
+        if (exSecret.isPresent()) {
+            String msg = " Credential with token " + credential.getToken() + " already exist";
+            LOGGER.error(msg);
+            throw new CredentialStoreException(msg, null);
+        }
+
+        String path = Constants.VAULT_RESOURCE_SECRETS_PATH + credential.getTenantId() + "/" + credential.getOwnerId()
+                + "/" + Constants.PASSWORD + "/" + credential.getToken();
+
+
+        PasswordSecret passwordSecret = new PasswordSecret(credential.getPassword());
+        vaultTemplate.write(path, passwordSecret);
+
+        VaultResponseSupport<PasswordSecret> response = vaultTemplate.read(path, PasswordSecret.class);
+
+        if (response == null || response.getData() == null && response.getData().getPassword() == null) {
+            String msg = " Password credential of tenant " + credential.getTenantId() +
+                    " of user " + credential.getOwnerId() + " is not saved in vault";
+            LOGGER.error(msg);
+            throw new CredentialStoreException(msg, null);
+        }
+
+        Secret secret = new Secret();
+        secret.setId(credential.getToken());
+        secret.setDiscription(credential.getDescription());
+        secret.setOwnerId(credential.getOwnerId());
+        secret.setOwnerType(credential.getResourceOwnerType().name());
+        secret.setSecretType(ResourceSecretType.PASSWORD.name());
+        secret.setTenantId(credential.getTenantId());
+        repository.save(secret);
+        return true;
+    }
+
+    /**
+     * save certificate credential in Vault and DB
+     *
+     * @param credential
+     * @return
+     */
+    public boolean saveCertificateCredential(CertificateCredential credential) {
+        Optional<Secret> exSecret = repository.findById(credential.getToken());
+
+        if (exSecret.isPresent()) {
+            String msg = " Credential with token " + credential.getToken() + " already exist";
+            LOGGER.error(msg);
+            throw new CredentialStoreException(msg, null);
+        }
+
+        String path = Constants.VAULT_RESOURCE_SECRETS_PATH + credential.getTenantId() + "/" + credential.getOwnerId() +
+                "/" + Constants.SSH_CREDENTIALS + "/" + credential.getToken();
+
+
+        Certificate certificate = new Certificate(credential.getCert(),
+                String.valueOf(credential.getLifetime()),
+                credential.getNotBefore(),
+                credential.getNotAfter(),
+                credential.getPrivateKey());
+
+        vaultTemplate.write(path, certificate);
+
+        VaultResponseSupport<Certificate> response = vaultTemplate.read(path, Certificate.class);
+
+        if (response == null || response.getData() == null && response.getData().getCertificate() == null) {
+            String msg = " Certificate credential of tenant " + credential.getTenantId() +
+                    " of user " + credential.getOwnerId() + " is not saved in vault";
+            LOGGER.error(msg);
+            throw new CredentialStoreException(msg, null);
+        }
+
+        Secret secret = new Secret();
+        secret.setId(credential.getToken());
+        secret.setDiscription(credential.getDescription());
+        secret.setOwnerId(credential.getOwnerId());
+        secret.setOwnerType(credential.getResourceOwnerType().name());
+        secret.setSecretType(ResourceSecretType.X509_CERTIFICATE.name());
+        secret.setTenantId(credential.getTenantId());
+        repository.save(secret);
+        return true;
+    }
+
+
+    /**
+     * delete existing credential
+     * @param tenantId
+     * @param token
+     * @return
+     */
+    public boolean deleteCredential(long tenantId, String token) {
+
+        Optional<Secret> exSec = repository.findById(token);
+
+        if (exSec.isEmpty()) {
+            return true;
+        }
+
+        Secret secret = exSec.get();
+
+        String type = null;
+
+        if (secret.getSecretType().equals(ResourceSecretType.SSH.name())) {
+            type = Constants.SSH_CREDENTIALS;
+        } else if (secret.getSecretType().equals(ResourceSecretType.PASSWORD.name())) {
+            type = Constants.PASSWORD;
+        } else if (secret.getSecretType().equals(ResourceSecretType.X509_CERTIFICATE.name())) {
+            type = Constants.CERTIFICATES;
+        }
+
+
+        String path = Constants.VAULT_RESOURCE_SECRETS_PATH + tenantId + "/" + secret.getOwnerId() +
+                "/" + type + "/" + token;
+
+        vaultTemplate.delete(path);
+
+        repository.delete(secret);
+        return true;
+
+    }
+
+
+
+
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/PasswordCredential.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/PasswordCredential.java
new file mode 100644
index 0000000..6b7b03c
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/PasswordCredential.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.manager.adaptor.outbound;
+
+import com.google.protobuf.GeneratedMessageV3;
+
+/**
+ * This class creates PasswordCredentials from gRPC PasswordCredential
+ */
+public class PasswordCredential extends ResourceCredential {
+
+    private String password;
+
+    public PasswordCredential(GeneratedMessageV3 message) {
+        super(message);
+        if (message instanceof org.apache.custos.resource.secret.service.PasswordCredential) {
+          this.password =   ((org.apache.custos.resource.secret.service.PasswordCredential) message).getPassword();
+        }
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/ResourceCredential.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/ResourceCredential.java
new file mode 100644
index 0000000..27b6b10
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/ResourceCredential.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.manager.adaptor.outbound;
+
+import com.google.protobuf.GeneratedMessageV3;
+import org.apache.custos.resource.secret.manager.Credential;
+import org.apache.custos.resource.secret.service.CertificateCredential;
+import org.apache.custos.resource.secret.service.PasswordCredential;
+import org.apache.custos.resource.secret.service.SSHCredential;
+import org.apache.custos.resource.secret.service.*;
+
+import java.util.UUID;
+
+public class ResourceCredential implements Credential {
+
+    private String ownerId;
+
+    private String token;
+
+    private String description;
+
+    private ResourceOwnerType resourceOwnerType;
+
+    private long tenantId;
+
+
+    public ResourceCredential(GeneratedMessageV3 message) {
+
+        this.token = generateToken();
+
+        if (message instanceof SSHCredential) {
+            SecretMetadata metadata = ((SSHCredential) message).getMetadata();
+            this.description = metadata.getDescription();
+            this.ownerId = metadata.getOwnerId();
+            this.tenantId = metadata.getTenantId();
+            this.resourceOwnerType = ResourceOwnerType.TENANT;
+
+        } else if (message instanceof CertificateCredential) {
+            SecretMetadata metadata = ((CertificateCredential) message).getMetadata();
+            this.description = metadata.getDescription();
+            this.ownerId = metadata.getOwnerId();
+            this.tenantId = metadata.getTenantId();
+            this.resourceOwnerType = ResourceOwnerType.TENANT;
+
+        } else if (message instanceof PasswordCredential) {
+            SecretMetadata metadata = ((PasswordCredential) message).getMetadata();
+            this.description = metadata.getDescription();
+            this.ownerId = metadata.getOwnerId();
+            this.tenantId = metadata.getTenantId();
+            this.resourceOwnerType = ResourceOwnerType.TENANT;
+        }
+    }
+
+    public String getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(String ownerId) {
+        this.ownerId = ownerId;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public ResourceOwnerType getResourceOwnerType() {
+        return resourceOwnerType;
+    }
+
+    public void setResourceOwnerType(ResourceOwnerType resourceOwnerType) {
+        this.resourceOwnerType = resourceOwnerType;
+    }
+
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+
+    private static String generateToken() {
+
+        return UUID.randomUUID().toString();
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/SSHCredential.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/SSHCredential.java
new file mode 100644
index 0000000..5e2d6eb
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/manager/adaptor/outbound/SSHCredential.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.manager.adaptor.outbound;
+
+import com.google.protobuf.GeneratedMessageV3;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.KeyPair;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+import java.io.File;
+import java.util.UUID;
+
+
+/**
+ * This class creates SSH credential from gRPC SSH Credential
+ */
+public class SSHCredential extends ResourceCredential {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SSHCredential.class);
+
+    private String publicKey;
+    private String privateKey;
+    private String passPhrase;
+
+    public SSHCredential(GeneratedMessageV3 message) throws Exception {
+        super(message);
+       if (message instanceof org.apache.custos.resource.secret.service.SSHCredential) {
+
+         this.passPhrase =  ((org.apache.custos.resource.secret.service.SSHCredential) message).getPassphrase();
+         this.privateKey = ((org.apache.custos.resource.secret.service.SSHCredential) message).getPrivateKey();
+         this.publicKey = ((org.apache.custos.resource.secret.service.SSHCredential) message).getPublicKey();
+
+         if (passPhrase == null || passPhrase.trim().equals("")) {
+             this.passPhrase = String.valueOf(UUID.randomUUID());
+         }
+          this.generateKeyPair(this.passPhrase);
+
+       }
+
+    }
+
+    public String getPublicKey() {
+        return publicKey;
+    }
+
+    public void setPublicKey(String publicKey) {
+        this.publicKey = publicKey;
+    }
+
+    public String getPrivateKey() {
+        return privateKey;
+    }
+
+    public void setPrivateKey(String privateKey) {
+        this.privateKey = privateKey;
+    }
+
+    public String getPassPhrase() {
+        return passPhrase;
+    }
+
+    public void setPassPhrase(String passPhrase) {
+        this.passPhrase = passPhrase;
+    }
+
+    private void  generateKeyPair(String passPhrase) throws Exception{
+        JSch jsch=new JSch();
+        try{
+            KeyPair kpair= KeyPair.genKeyPair(jsch, KeyPair.RSA, 2048);
+            File file = File.createTempFile("id_rsa", "");
+            String fileName = file.getAbsolutePath();
+
+            kpair.writePrivateKey(fileName, passPhrase.getBytes());
+            kpair.writePublicKey(fileName + ".pub"  , "");
+            kpair.dispose();
+            byte[] priKey = FileUtils.readFileToByteArray(new File(fileName));
+
+            byte[] pubKey = FileUtils.readFileToByteArray(new File(fileName + ".pub"));
+            this.privateKey = new String(priKey);
+            this.publicKey = new String(pubKey);
+
+        }
+        catch(Exception e){
+            LOGGER.error("Error while creating key pair", e);
+            throw new Exception("Error while creating key pair", e);
+        }
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/local/model/Secret.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/local/model/Secret.java
new file mode 100644
index 0000000..fc74e80
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/local/model/Secret.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.persistance.local.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "secret")
+@EntityListeners(AuditingEntityListener.class)
+public class Secret {
+
+    @Id
+    @Column(nullable = false)
+    private String id;
+
+    @Column(nullable = false)
+    private long tenantId;
+
+    @Column(nullable = false)
+    private String ownerId;
+
+
+    private String type;
+
+    @Column(nullable = false)
+    private String ownerType;
+
+    @Column(nullable = false)
+    private String secretType;
+
+    private String discription;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedAt;
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(String ownerId) {
+        this.ownerId = ownerId;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getOwnerType() {
+        return ownerType;
+    }
+
+    public void setOwnerType(String ownerType) {
+        this.ownerType = ownerType;
+    }
+
+    public String getSecretType() {
+        return secretType;
+    }
+
+    public void setSecretType(String secretType) {
+        this.secretType = secretType;
+    }
+
+    public String getDiscription() {
+        return discription;
+    }
+
+    public void setDiscription(String discription) {
+        this.discription = discription;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLastModifiedAt() {
+        return lastModifiedAt;
+    }
+
+    public void setLastModifiedAt(Date lastModifiedAt) {
+        this.lastModifiedAt = lastModifiedAt;
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/local/repository/SecretRepository.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/local/repository/SecretRepository.java
new file mode 100644
index 0000000..34ee966
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/local/repository/SecretRepository.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.persistance.local.repository;
+
+import org.apache.custos.resource.secret.persistance.local.model.Secret;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface SecretRepository extends JpaRepository<Secret, String> {
+
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/vault/Certificate.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/vault/Certificate.java
new file mode 100644
index 0000000..8e51059
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/vault/Certificate.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.persistance.vault;
+
+/**
+ * Certificate secret representation
+ */
+public class Certificate {
+
+    private String certificate;
+
+    private String lifetime;
+
+    private String notBefore;
+
+    private String notAfter;
+
+    private String privateKey;
+
+    public Certificate(String certificate, String lifetime, String notBefore, String notAfter, String privateKey) {
+        this.certificate = certificate;
+        this.lifetime = lifetime;
+        this.notBefore = notBefore;
+        this.notAfter = notAfter;
+        this.privateKey = privateKey;
+    }
+
+    public Certificate() {
+
+    }
+
+    public String getCertificate() {
+        return certificate;
+    }
+
+    public void setCertificate(String certificate) {
+        this.certificate = certificate;
+    }
+
+    public String getLifetime() {
+        return lifetime;
+    }
+
+    public void setLifetime(String lifetime) {
+        this.lifetime = lifetime;
+    }
+
+    public String getNotBefore() {
+        return notBefore;
+    }
+
+    public void setNotBefore(String notBefore) {
+        this.notBefore = notBefore;
+    }
+
+    public String getNotAfter() {
+        return notAfter;
+    }
+
+    public void setNotAfter(String notAfter) {
+        this.notAfter = notAfter;
+    }
+
+    public String getPrivateKey() {
+        return privateKey;
+    }
+
+    public void setPrivateKey(String privateKey) {
+        this.privateKey = privateKey;
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/vault/PasswordSecret.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/vault/PasswordSecret.java
new file mode 100644
index 0000000..1b094c4
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/vault/PasswordSecret.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.persistance.vault;
+
+/**
+ * Password credential representation
+ */
+public class PasswordSecret {
+
+    private String password;
+
+    public PasswordSecret() {
+
+    }
+
+
+    public PasswordSecret(String password) {
+        this.password = password;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/vault/SSHCredentialSecrets.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/vault/SSHCredentialSecrets.java
new file mode 100644
index 0000000..581046f
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/persistance/vault/SSHCredentialSecrets.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.persistance.vault;
+
+/**
+ * SSH credential secret  representation of Vault
+ */
+public class SSHCredentialSecrets {
+
+    private String privateKey;
+    private String publicKey;
+    private String passphrase;
+
+
+    public SSHCredentialSecrets(String privateKey, String publicKey, String passphrase) {
+        this.privateKey = privateKey;
+        this.publicKey = publicKey;
+        this.passphrase = passphrase;
+    }
+
+    public SSHCredentialSecrets() {
+
+    }
+
+    public String getPrivateKey() {
+        return privateKey;
+    }
+
+    public void setPrivateKey(String privateKey) {
+        this.privateKey = privateKey;
+    }
+
+    public String getPublicKey() {
+        return publicKey;
+    }
+
+    public void setPublicKey(String publicKey) {
+        this.publicKey = publicKey;
+    }
+
+    public String getPassphrase() {
+        return passphrase;
+    }
+
+    public void setPassphrase(String passphrase) {
+        this.passphrase = passphrase;
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/service/ResourceSecretService.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/service/ResourceSecretService.java
new file mode 100644
index 0000000..2f50e15
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/service/ResourceSecretService.java
@@ -0,0 +1,329 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.service;
+
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.core.services.commons.StatusUpdater;
+import org.apache.custos.core.services.commons.persistance.model.OperationStatus;
+import org.apache.custos.resource.secret.manager.Credential;
+import org.apache.custos.resource.secret.manager.CredentialGeneratorFactory;
+import org.apache.custos.resource.secret.manager.adaptor.outbound.CredentialWriter;
+import org.apache.custos.resource.secret.manager.adaptor.inbound.CredentialReader;
+import org.apache.custos.resource.secret.utils.Operations;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ * This class is responsible for handling resource secrets, such as SSH credentials, password credentials
+ */
+@GRpcService
+public class ResourceSecretService extends ResourceSecretServiceGrpc.ResourceSecretServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ResourceSecretService.class);
+
+
+    @Autowired
+    private StatusUpdater statusUpdater;
+
+    @Autowired
+    private CredentialGeneratorFactory credentialGeneratorFactory;
+
+    @Autowired
+    private CredentialWriter credentialWriter;
+
+    @Autowired
+    private CredentialReader credentialReader;
+
+
+    @Override
+    public void getSecret(GetSecretRequest request, StreamObserver<SecretMetadata> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to getSecret in tenant " + request.getMetadata().getTenantId() +
+                    " of owner " + request.getMetadata().getOwnerId() + " with token  " + request.getMetadata().getToken());
+
+            responseObserver.onNext(SecretMetadata.newBuilder().build());
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching secret with " + request.getMetadata().getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getAllResourceCredentialSummaries(GetResourceCredentialSummariesRequest request, StreamObserver<ResourceCredentialSummaries> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to getAllResourceCredentialSummaries in tenant " + request.getTenantId() +
+                    " of owner " + request.getOwnerId());
+
+            List<SecretMetadata> metadataList = credentialReader.
+                    getAllCredentialSummaries(request.getTenantId(), request.getAccessibleTokensList());
+
+            ResourceCredentialSummaries resourceCredentialSummaries = ResourceCredentialSummaries.newBuilder()
+                    .addAllMetadata(metadataList)
+                    .build();
+
+            responseObserver.onNext(resourceCredentialSummaries);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching credential summaries  " +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addSSHCredential(SSHCredential request, StreamObserver<AddResourceCredentialResponse> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to addSSHCredential in tenant " + request.getMetadata().getTenantId() +
+                    " of owner " + request.getMetadata().getOwnerId() + " with token  " + request.getMetadata().getToken());
+
+            Credential credential = credentialGeneratorFactory.getCredential(request);
+            org.apache.custos.resource.secret.manager.adaptor.outbound.SSHCredential sshCredential =
+                    (org.apache.custos.resource.secret.manager.adaptor.outbound.SSHCredential) credential;
+
+            credentialWriter.
+                    saveSSHCredential(sshCredential);
+
+
+            statusUpdater.updateStatus(Operations.ADD_SSH_CREDENTIAL.name(), OperationStatus.SUCCESS,
+                    request.getMetadata().getTenantId(), request.getMetadata().getOwnerId());
+
+
+            AddResourceCredentialResponse resourceCredentialResponse = AddResourceCredentialResponse
+                    .newBuilder()
+                    .setToken(sshCredential.getToken())
+                    .build();
+            responseObserver.onNext(resourceCredentialResponse);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while adding SSH credentials " + request.getMetadata().getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addPasswordCredential(PasswordCredential request, StreamObserver<AddResourceCredentialResponse> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to addPasswordCredential in tenant " + request.getMetadata().getTenantId() +
+                    " of owner " + request.getMetadata().getOwnerId() + " with token  " + request.getMetadata().getToken());
+
+            Credential credential = credentialGeneratorFactory.getCredential(request);
+            org.apache.custos.resource.secret.manager.adaptor.outbound.PasswordCredential passwordCredential =
+                    (org.apache.custos.resource.secret.manager.adaptor.outbound.PasswordCredential) credential;
+
+            credentialWriter.
+                    savePasswordCredential(passwordCredential);
+
+
+            statusUpdater.updateStatus(Operations.ADD_PASSWORD_CREDENTIAL.name(), OperationStatus.SUCCESS,
+                    request.getMetadata().getTenantId(), request.getMetadata().getOwnerId());
+
+            AddResourceCredentialResponse resourceCredentialResponse = AddResourceCredentialResponse
+                    .newBuilder()
+                    .setToken(passwordCredential.getToken())
+                    .build();
+            responseObserver.onNext(resourceCredentialResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while adding password credentials " + request.getMetadata().getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addCertificateCredential(CertificateCredential request, StreamObserver<AddResourceCredentialResponse> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to addCertificateCredential in tenant " + request.getMetadata().getTenantId() +
+                    " of owner " + request.getMetadata().getOwnerId() + " with token  " + request.getMetadata().getToken());
+
+
+            Credential credential = credentialGeneratorFactory.getCredential(request);
+            org.apache.custos.resource.secret.manager.adaptor.outbound.CertificateCredential certificateCredential =
+                    (org.apache.custos.resource.secret.manager.adaptor.outbound.CertificateCredential) credential;
+
+            credentialWriter.
+                    saveCertificateCredential(certificateCredential);
+
+            statusUpdater.updateStatus(Operations.ADD_CERTIFICATE_CREDENTIAL.name(), OperationStatus.SUCCESS,
+                    request.getMetadata().getTenantId(), request.getMetadata().getOwnerId());
+
+            AddResourceCredentialResponse resourceCredentialResponse = AddResourceCredentialResponse
+                    .newBuilder()
+                    .setToken(certificateCredential.getToken())
+                    .build();
+            responseObserver.onNext(resourceCredentialResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while adding certificate credential secret " + request.getMetadata().getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getResourceCredentialSummary(GetResourceCredentialByTokenRequest request, StreamObserver<SecretMetadata> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to getResourceCredentialSummary in tenant " + request.getTenantId() +
+                    " with token  " + request.getToken());
+
+            SecretMetadata metadata = credentialReader.getCredentialSummary(request.getTenantId(), request.getToken());
+
+            responseObserver.onNext(metadata);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching resource credential summaries " + request.getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getSSHCredential(GetResourceCredentialByTokenRequest request, StreamObserver<SSHCredential> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to getSSHCredential in tenant " + request.getTenantId() +
+                    " with token  " + request.getToken());
+
+            SSHCredential sshCredential = credentialReader.getSSHCredential(request.getTenantId(), request.getToken());
+            responseObserver.onNext(sshCredential);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching SSH credential " + request.getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getPasswordCredential(GetResourceCredentialByTokenRequest request, StreamObserver<PasswordCredential> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to getPasswordCredential in tenant " + request.getTenantId() +
+                    " with token  " + request.getToken());
+
+            PasswordCredential passwordCredential = credentialReader.
+                    getPasswordCredential(request.getTenantId(), request.getToken());
+            responseObserver.onNext(passwordCredential);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching password credential " + request.getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getCertificateCredential(GetResourceCredentialByTokenRequest request, StreamObserver<CertificateCredential> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to getCertificateCredential in tenant " + request.getTenantId() +
+                    " with token  " + request.getToken());
+
+            CertificateCredential certificateCredential = credentialReader.
+                    getCertificateCredential(request.getTenantId(), request.getToken());
+            responseObserver.onNext(certificateCredential);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching certificate credential " + request.getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteSSHCredential(GetResourceCredentialByTokenRequest request, StreamObserver<ResourceCredentialOperationStatus> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to deleteSSHCredential in tenant " + request.getTenantId() +
+                    " with token  " + request.getToken());
+
+            boolean status = credentialWriter.deleteCredential(request.getTenantId(), request.getToken());
+
+            statusUpdater.updateStatus(Operations.DELETE_SSH_CREDENTIAL.name(), OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+
+            ResourceCredentialOperationStatus operationStatus = ResourceCredentialOperationStatus
+                    .newBuilder()
+                    .setStatus(status)
+                    .build();
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while deleting SSH secret " + request.getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deletePWDCredential(GetResourceCredentialByTokenRequest request, StreamObserver<ResourceCredentialOperationStatus> responseObserver) {
+        try {
+            LOGGER.debug(" Request received to deletePWDCredential in tenant " + request.getTenantId() +
+                    " with token  " + request.getToken());
+
+            boolean status = credentialWriter.deleteCredential(request.getTenantId(), request.getToken());
+
+            statusUpdater.updateStatus(Operations.DELETE_PASSWORD_CREDENTIAL.name(), OperationStatus.SUCCESS,
+                    request.getTenantId(), request.getPerformedBy());
+
+            ResourceCredentialOperationStatus operationStatus = ResourceCredentialOperationStatus
+                    .newBuilder()
+                    .setStatus(status)
+                    .build();
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while deleting password credential " + request.getToken() +
+                    " : " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/utils/Constants.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/utils/Constants.java
new file mode 100644
index 0000000..0b34ac1
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/utils/Constants.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.utils;
+
+public final class Constants {
+
+    public static final String VAULT_RESOURCE_SECRETS_PATH = "/resourcesecret/";
+    public static final String SSH_CREDENTIALS = "ssh";
+    public static  final String CERTIFICATES = "certificates";
+    public static final String PASSWORD = "passwd";
+
+
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/utils/Operations.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/utils/Operations.java
new file mode 100644
index 0000000..6749405
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/utils/Operations.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.utils;
+
+public enum Operations {
+
+    ADD_SSH_CREDENTIAL,
+    ADD_CERTIFICATE_CREDENTIAL,
+    ADD_PASSWORD_CREDENTIAL,
+    DELETE_SSH_CREDENTIAL,
+    DELETE_CERTIFICATE_CREDENTIAL,
+    DELETE_PASSWORD_CREDENTIAL
+
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/validator/InputValidator.java b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/validator/InputValidator.java
new file mode 100644
index 0000000..b5d68ec
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/java/org/apache/custos/resource/secret/validator/InputValidator.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.validator;
+
+
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.core.services.commons.exceptions.MissingParameterException;
+import org.apache.custos.resource.secret.service.*;
+
+
+/**
+ * This class validates the  requests
+ */
+public class InputValidator implements Validator {
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "getAllResourceCredentialSummaries":
+                validateGetAllResourceCredentialSummaries(obj, methodName);
+                break;
+            case "addSSHCredential":
+                validateAddSSHCredential(obj, methodName);
+                break;
+            case "addPasswordCredential":
+                validateAddPasswordCredential(obj, methodName);
+                break;
+            case "addCertificateCredential":
+                validateAddCertificateCredential(obj, methodName);
+                break;
+            case "getPasswordCredential":
+            case "getCertificateCredential":
+            case "getSSHCredential":
+            case "deleteSSHCredential":
+            case "deletePWDCredential":
+            case "getResourceCredentialSummary":
+                validateGetResourceCredentialByToken(obj, methodName);
+                break;
+            default:
+        }
+    }
+
+    private boolean validateGetResourceCredentialByToken(Object obj, String methodName) {
+        if (obj instanceof GetResourceCredentialByTokenRequest) {
+            GetResourceCredentialByTokenRequest request = (GetResourceCredentialByTokenRequest) obj;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("TenantId should be set", null);
+            }
+
+            if (request.getToken() == null || request.getToken().equals("")) {
+                throw new MissingParameterException("Token should not be null", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + methodName);
+        }
+        return true;
+
+
+    }
+
+    private boolean validateGetAllResourceCredentialSummaries(Object obj, String methodName) {
+        if (obj instanceof GetResourceCredentialSummariesRequest) {
+            GetResourceCredentialByTokenRequest request = (GetResourceCredentialByTokenRequest) obj;
+
+            if (request.getTenantId() == 0) {
+                throw new MissingParameterException("TenantId should be set", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateAddSSHCredential(Object obj, String methodName) {
+        if (obj instanceof SSHCredential) {
+            SSHCredential request = (SSHCredential) obj;
+
+            validateSecretMetadata(request.getMetadata());
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateAddPasswordCredential(Object obj, String methodName) {
+        if (obj instanceof PasswordCredential) {
+            PasswordCredential request = (PasswordCredential) obj;
+
+            validateSecretMetadata(request.getMetadata());
+
+            if (request.getPassword() == null || request.getPassword().trim().equals("")) {
+                throw new MissingParameterException("Password should not be  null ", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateAddCertificateCredential(Object obj, String methodName) {
+        if (obj instanceof CertificateCredential) {
+            CertificateCredential request = (CertificateCredential) obj;
+
+            validateSecretMetadata(request.getMetadata());
+
+            if (request.getX509Cert() == null || request.getX509Cert().trim().equals("")) {
+                throw new MissingParameterException("Certificate should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + methodName);
+        }
+        return true;
+    }
+
+
+    private boolean validateSecretMetadata(SecretMetadata metadata) {
+
+        if (metadata.getOwnerId() == null || metadata.getOwnerId().trim().equals("")) {
+            throw new MissingParameterException("OwnerId should not be null", null);
+        }
+
+        if (metadata.getTenantId() == 0) {
+            throw new MissingParameterException("TenantId should be set", null);
+        }
+
+        return true;
+    }
+
+
+}
diff --git a/custos-core-services/resource-secret-core-service/src/main/proto/ResourceSecretService.proto b/custos-core-services/resource-secret-core-service/src/main/proto/ResourceSecretService.proto
new file mode 100644
index 0000000..0ca5a8d
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/proto/ResourceSecretService.proto
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.resource.secret.service;
+
+
+enum ResourceOwnerType {
+    TENANT_USER = 0;
+    CUSTOS = 1;
+    TENANT = 2;
+}
+
+enum ResourceType {
+    SERVER_CERTIFICATE = 0;
+    JWT_SIGNING_CERTIFICATE = 1;
+    VAULT_CREDENTIAL = 2;
+}
+
+enum ResourceSource {
+    KUBE = 0;
+    LOCAL = 1;
+    EXTERNAL = 2;
+    LETSENCRYPT = 3;
+}
+
+enum ResourceSecretType {
+    SSH = 0;
+    PASSWORD = 1;
+    X509_CERTIFICATE = 2;
+}
+
+message SecretMetadata {
+    ResourceOwnerType owner_type = 1;
+    ResourceType resource_type = 2;
+    ResourceSource source = 3;
+    string name = 4;
+    string value = 5;
+    ResourceSecretType type = 6;
+    int64 tenantId = 7;
+    string owner_id = 8;
+    int64 persisted_time = 9;
+    string token = 10;
+    string description = 11;
+    string client_id = 12;
+
+}
+
+
+message GetSecretRequest {
+    SecretMetadata metadata = 1;
+    int64 tenantId = 2;
+    string clientId = 3;
+    string clientSec = 4;
+    string accessToken = 5;
+}
+
+
+message CertificateCredential {
+    SecretMetadata metadata = 1;
+    string x509_cert = 3;
+    string not_after = 4;
+    string private_key = 5;
+    int64 life_time = 6;
+    string not_before = 7;
+}
+
+message PasswordCredential {
+    SecretMetadata metadata = 1;
+    string password = 3;
+}
+
+message SSHCredential {
+    SecretMetadata metadata = 1;
+    string passphrase = 3;
+    string public_key = 4;
+    string private_key = 5;
+}
+
+
+message GetResourceCredentialByTokenRequest {
+    int64 tenantId = 1;
+    string token = 2;
+    string performed_by = 3;
+    string client_id = 4;
+}
+
+message GetResourceCredentialSummariesRequest {
+    ResourceType type = 1;
+    repeated string accessible_tokens = 2;
+    int64 tenantId = 3;
+    string owner_id = 4;
+    bool all_types = 5;
+    string client_id =6;
+}
+
+message ResourceCredentialSummaries {
+    repeated SecretMetadata metadata = 1;
+}
+
+message AddResourceCredentialResponse {
+    string token = 1;
+}
+
+message ResourceCredentialOperationStatus {
+    bool status = 1;
+}
+
+
+service ResourceSecretService {
+    rpc getSecret (GetSecretRequest) returns (SecretMetadata);
+
+    rpc getResourceCredentialSummary (GetResourceCredentialByTokenRequest) returns (SecretMetadata);
+    rpc getAllResourceCredentialSummaries (GetResourceCredentialSummariesRequest) returns (ResourceCredentialSummaries);
+    rpc addSSHCredential (SSHCredential) returns (AddResourceCredentialResponse);
+    rpc addPasswordCredential (PasswordCredential) returns (AddResourceCredentialResponse);
+    rpc addCertificateCredential (CertificateCredential) returns (AddResourceCredentialResponse);
+
+    rpc getSSHCredential (GetResourceCredentialByTokenRequest) returns (SSHCredential);
+    rpc getPasswordCredential (GetResourceCredentialByTokenRequest) returns (PasswordCredential);
+    rpc getCertificateCredential (GetResourceCredentialByTokenRequest) returns (CertificateCredential);
+
+    rpc deleteSSHCredential (GetResourceCredentialByTokenRequest) returns (ResourceCredentialOperationStatus);
+    rpc deletePWDCredential (GetResourceCredentialByTokenRequest) returns (ResourceCredentialOperationStatus);
+    rpc deleteCertificateCredential (GetResourceCredentialByTokenRequest) returns (ResourceCredentialOperationStatus);
+}
\ No newline at end of file
diff --git a/custos-core-services/resource-secret-core-service/src/main/resources/application.properties b/custos-core-services/resource-secret-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..c34ddd3
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/resources/application.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=resourceSecretCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_resource_secret?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
+
diff --git a/custos-core-services/resource-secret-core-service/src/main/resources/bootstrap.properties b/custos-core-services/resource-secret-core-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..da2d184
--- /dev/null
+++ b/custos-core-services/resource-secret-core-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,25 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.vault.token={{vault_token}}
+spring.cloud.vault.scheme=http
+spring.cloud.vault.host=vault.custos.scigap.org
+spring.cloud.vault.port=30249
+spring.cloud.vault.uri=http://vault.custos.scigap.org:30249
+spring.cloud.vault.authentication=token
diff --git a/custos-core-services/sharing-core-service/Dockerfile b/custos-core-services/sharing-core-service/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/sharing-core-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/sharing-core-service/pom.xml b/custos-core-services/sharing-core-service/pom.xml
new file mode 100644
index 0000000..c78d457
--- /dev/null
+++ b/custos-core-services/sharing-core-service/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sharing-core-service</artifactId>
+    <dependencies>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.jcraft</groupId>
+            <artifactId>jsch</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/sharing-core-service/src/main/helm/.helmignore b/custos-core-services/sharing-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/sharing-core-service/src/main/helm/Chart.yaml b/custos-core-services/sharing-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..ab51a2a
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of sharing core service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/sharing-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/sharing-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/sharing-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/sharing-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/sharing-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/sharing-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..31e54a6
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,64 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/sharing-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/sharing-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/sharing-core-service/src/main/helm/templates/service.yaml b/custos-core-services/sharing-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/sharing-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/sharing-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/sharing-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/sharing-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/sharing-core-service/src/main/helm/values.yaml b/custos-core-services/sharing-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..fa8b2ef
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/helm/values.yaml
@@ -0,0 +1,79 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java
new file mode 100644
index 0000000..cb28bb3
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.apache.custos.sharing.validator.InputValidator;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication
+@EnableJpaAuditing
+@EnableJpaRepositories(basePackages = "org.apache.custos")
+@ComponentScan(basePackages = "org.apache.custos")
+@EntityScan(basePackages = "org.apache.custos")
+public class SharingServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(SharingServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator){
+        return new ServiceInterceptor(validator);
+    }
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityMapper.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityMapper.java
new file mode 100644
index 0000000..a43e539
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityMapper.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.mapper;
+
+
+import com.google.protobuf.ByteString;
+import org.apache.custos.sharing.persistance.model.Entity;
+import org.apache.custos.sharing.persistance.model.EntityType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.rowset.serial.SerialBlob;
+import java.sql.Blob;
+import java.sql.Date;
+import java.sql.SQLException;
+
+public class EntityMapper {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(EntityMapper.class);
+
+
+    public static Entity createEntity(org.apache.custos.sharing.service.Entity entity, long tenantId,
+                                      EntityType type) throws SQLException {
+
+        Entity perEntity = new Entity();
+
+        String internalId = entity.getId() + "@" + tenantId;
+
+
+        perEntity.setEntityType(type);
+        perEntity.setId(internalId);
+        perEntity.setExternalId(entity.getId());
+        perEntity.setName(entity.getName());
+        perEntity.setTenantId(tenantId);
+        perEntity.setOwnerId(entity.getOwnerId());
+        perEntity.setSharedCount(entity.getSharedCount());
+
+        if (entity.getBinaryData() != null && !entity.getBinaryData().isEmpty()) {
+            perEntity.setBinaryData(new SerialBlob(entity.getBinaryData().toByteArray()));
+        }
+
+        if (entity.getDescription() != null && !entity.getDescription().trim().equals("")) {
+            perEntity.setDescription(entity.getDescription());
+        }
+
+        if (entity.getFullText() != null && !entity.getFullText().trim().equals("")) {
+            perEntity.setFullText(entity.getFullText());
+        }
+
+        if (entity.getParentId() != null && !entity.getParentId().trim().equals("")) {
+            perEntity.setExternalParentId(entity.getParentId());
+        }
+
+        if (entity.getOriginalCreationTime() > 0) {
+            perEntity.setOriginalCreatedTime(new Date(entity.getOriginalCreationTime()));
+        }
+
+        return perEntity;
+
+
+    }
+
+
+    public static org.apache.custos.sharing.service.Entity createEntity(Entity entity) throws SQLException {
+
+        org.apache.custos.sharing.service.Entity.Builder builder =
+                org.apache.custos.sharing.service.Entity
+                        .newBuilder();
+        builder
+                .setId(entity.getExternalId())
+                .setCreatedAt(entity.getCreatedAt().getTime())
+                .setUpdatedAt(entity.getLastModifiedAt().getTime())
+                .setName(entity.getName())
+                .setOriginalCreationTime(entity.getCreatedAt().getTime())
+                .setOwnerId(entity.getOwnerId())
+                .setType(entity.getEntityType().getExternalId())
+                .setSharedCount(entity.getSharedCount());
+
+        if (entity.getExternalParentId() != null) {
+            builder.setParentId(entity.getExternalParentId());
+        }
+
+        if (entity.getDescription() != null) {
+            builder.setDescription(entity.getDescription());
+        }
+
+        if (entity.getBinaryData() != null) {
+            Blob blob = entity.getBinaryData();
+            int len = (int) blob.length();
+            byte[] blobAsBytes = blob.getBytes(1, len);
+            builder.setBinaryData(ByteString.copyFrom(blobAsBytes));
+        }
+
+        if (entity.getFullText() != null) {
+            builder.setFullText(entity.getFullText());
+        }
+
+        return builder.build();
+
+    }
+
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityTypeMapper.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityTypeMapper.java
new file mode 100644
index 0000000..a517c26
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityTypeMapper.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.mapper;
+
+import org.apache.custos.sharing.persistance.model.EntityType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Date;
+
+public class EntityTypeMapper {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(EntityTypeMapper.class);
+
+    public static EntityType createEntityType(org.apache.custos.sharing.service.EntityType entityType, long tenantId) {
+
+        EntityType type = new EntityType();
+        String id = entityType.getId() + "@" + tenantId;
+        type.setId(id);
+        type.setName(entityType.getName());
+        type.setTenantId(tenantId);
+        type.setExternalId(entityType.getId());
+        if (entityType.getDescription() != null && ! entityType.getDescription().trim().equals("")) {
+            type.setDescription(entityType.getDescription());
+        }
+
+        if (entityType.getCreatedAt() > 0 ) {
+            type.setCreatedAt(new Date(entityType.getCreatedAt()));
+        }
+        return type;
+    }
+
+
+    public static org.apache.custos.sharing.service.EntityType createEntityType(EntityType entityType) {
+
+        org.apache.custos.sharing.service.EntityType.Builder builder = org.apache.custos.sharing.service.EntityType
+                .newBuilder()
+                .setId(entityType.getExternalId())
+                .setCreatedAt(entityType.getCreatedAt().getTime())
+                .setName(entityType.getName())
+                .setUpdatedAt(entityType.getLastModifiedAt().getTime());
+
+        if (entityType.getDescription() != null) {
+            builder.setDescription(entityType.getDescription());
+        }
+
+        return builder.build();
+
+    }
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/PermissionTypeMapper.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/PermissionTypeMapper.java
new file mode 100644
index 0000000..ba420da
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/PermissionTypeMapper.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.mapper;
+
+import org.apache.custos.sharing.persistance.model.PermissionType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Date;
+
+public class PermissionTypeMapper {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(PermissionTypeMapper.class);
+
+    public static PermissionType createPermissionType(org.apache.custos.sharing.service.PermissionType entityType, long tenantId) {
+
+        PermissionType type = new PermissionType();
+        String id = entityType.getId() + "@" + tenantId;
+        type.setId(id);
+        type.setName(entityType.getName());
+        type.setTenantId(tenantId);
+        type.setExternalId(entityType.getId());
+        if (entityType.getDescription() != null && ! entityType.getDescription().trim().equals("")) {
+            type.setDescription(entityType.getDescription());
+        }
+        if (entityType.getCreatedAt() > 0 ) {
+            type.setCreatedAt(new Date(entityType.getCreatedAt()));
+        }
+        return type;
+    }
+
+    public static org.apache.custos.sharing.service.PermissionType createPermissionType(PermissionType type) {
+        org.apache.custos.sharing.service.PermissionType.Builder builder =
+
+                org.apache.custos.sharing.service.PermissionType
+                        .newBuilder()
+                        .setId(type.getExternalId())
+                        .setCreatedAt(type.getCreatedAt().getTime())
+                        .setName(type.getName())
+                        .setUpdatedAt(type.getLastModifiedAt().getTime());
+
+        if (type.getDescription() != null) {
+            builder.setDescription(type.getDescription());
+        }
+
+        return builder.build();
+
+    }
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/SharingMapper.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/SharingMapper.java
new file mode 100644
index 0000000..fd1ac13
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/SharingMapper.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.mapper;
+
+import org.apache.custos.sharing.persistance.model.Entity;
+import org.apache.custos.sharing.persistance.model.PermissionType;
+import org.apache.custos.sharing.persistance.model.Sharing;
+import org.apache.custos.sharing.service.SharedOwners;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class SharingMapper {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SharingMapper.class);
+
+
+    public static Sharing createSharing(PermissionType permissionType,
+                                        Entity entity,
+                                        Entity inheritedEntity,
+                                        String ownerId,
+                                        String ownerType,
+                                        String sharingType,
+                                        long tenantId) {
+
+        String id = entity.getId() + "_" +
+                inheritedEntity.getId() + "_" + ownerId + "_" + permissionType.getId() + "_" + tenantId;
+
+        Sharing sharing = new Sharing();
+        sharing.setSharingType(sharingType);
+        sharing.setEntity(entity);
+        sharing.setPermissionType(permissionType);
+        sharing.setAssociatingId(ownerId);
+        sharing.setAssociatingIdType(ownerType);
+        sharing.setInheritedParent(inheritedEntity);
+        sharing.setTenantId(tenantId);
+        sharing.setId(id);
+        return sharing;
+    }
+
+
+    public static Sharing getNewSharing(Sharing oldSharing, long tenantId, Entity entity) {
+        String id = entity.getId() + "_" +
+                oldSharing.getInheritedParent().getId() + "_" + oldSharing.getAssociatingId() + "_" + oldSharing.getPermissionType().getId() + "_" + tenantId;
+
+        Sharing sharing = new Sharing();
+        sharing.setSharingType(oldSharing.getSharingType());
+        sharing.setEntity(entity);
+        sharing.setPermissionType(oldSharing.getPermissionType());
+        sharing.setAssociatingId(oldSharing.getAssociatingId());
+        sharing.setAssociatingIdType(oldSharing.getAssociatingIdType());
+        sharing.setInheritedParent(oldSharing.getInheritedParent());
+        sharing.setCreatedAt(oldSharing.getCreatedAt());
+        sharing.setTenantId(tenantId);
+        sharing.setId(id);
+        return sharing;
+
+    }
+
+
+    public static SharedOwners getSharedOwners(List<Sharing> sharingList) {
+
+        SharedOwners.Builder builder = SharedOwners.newBuilder();
+
+        List<String> ownerIds = new ArrayList<>();
+
+        if (sharingList != null && !sharingList.isEmpty()) {
+
+            ownerIds = sharingList.stream().
+                    map(shr -> shr.getAssociatingId()).collect(Collectors.toList());
+
+        }
+
+        return builder.addAllOwnerIds(ownerIds).build();
+
+    }
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Entity.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Entity.java
new file mode 100644
index 0000000..6bad30f
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Entity.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.sql.Blob;
+import java.util.Date;
+import java.util.Set;
+
+@javax.persistence.Entity
+@Table(name = "entity")
+@EntityListeners(AuditingEntityListener.class)
+public class Entity {
+    @Id
+    @Column(nullable = false)
+    private String id;
+
+    @Column(nullable = false)
+    private String externalId;
+
+    @Column
+    private long tenantId;
+
+    @Column
+    private String externalParentId;
+
+    @Column(nullable = false)
+    private String ownerId;
+
+    @Column(nullable = false)
+    private String name;
+
+    @Column
+    private String description;
+
+    @Column
+    private String fullText;
+
+    @Column
+    private int sharedCount;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedAt;
+
+
+    @Column(nullable = true)
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date originalCreatedTime;
+
+
+    @Lob
+    @Column
+    private java.sql.Blob binaryData;
+
+
+    @JoinColumn(name = "entity_type_id")
+    @ManyToOne
+    private EntityType entityType;
+
+    @OneToMany(mappedBy = "entity", cascade = CascadeType.ALL)
+    private Set<Sharing> sharingSet;
+
+    @OneToMany(mappedBy = "inheritedParent", cascade = CascadeType.ALL)
+    private Set<Sharing> inheritedSharing;
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+
+    public String getExternalParentId() {
+        return externalParentId;
+    }
+
+    public void setExternalParentId(String externalParentId) {
+        this.externalParentId = externalParentId;
+    }
+
+    public String getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(String ownerId) {
+        this.ownerId = ownerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getFullText() {
+        return fullText;
+    }
+
+    public void setFullText(String fullText) {
+        this.fullText = fullText;
+    }
+
+    public int getSharedCount() {
+        return sharedCount;
+    }
+
+    public void setSharedCount(int sharedCount) {
+        this.sharedCount = sharedCount;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLastModifiedAt() {
+        return lastModifiedAt;
+    }
+
+    public void setLastModifiedAt(Date lastModifiedAt) {
+        this.lastModifiedAt = lastModifiedAt;
+    }
+
+    public Date getOriginalCreatedTime() {
+        return originalCreatedTime;
+    }
+
+    public void setOriginalCreatedTime(Date originalCreatedTime) {
+        this.originalCreatedTime = originalCreatedTime;
+    }
+
+    public Blob getBinaryData() {
+        return binaryData;
+    }
+
+    public void setBinaryData(Blob binaryData) {
+        this.binaryData = binaryData;
+    }
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public EntityType getEntityType() {
+        return entityType;
+    }
+
+    public void setEntityType(EntityType entityType) {
+        this.entityType = entityType;
+    }
+
+    public Set<Sharing> getSharingSet() {
+        return sharingSet;
+    }
+
+    public void setSharingSet(Set<Sharing> sharingSet) {
+        this.sharingSet = sharingSet;
+    }
+
+    public Set<Sharing> getInheritedSharing() {
+        return inheritedSharing;
+    }
+
+    public void setInheritedSharing(Set<Sharing> inheritedSharing) {
+        this.inheritedSharing = inheritedSharing;
+    }
+
+    public String getExternalId() {
+        return externalId;
+    }
+
+    public void setExternalId(String externalId) {
+        this.externalId = externalId;
+    }
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/EntityType.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/EntityType.java
new file mode 100644
index 0000000..7d38e58
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/EntityType.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.Entity;
+import javax.persistence.*;
+import java.util.Date;
+import java.util.Set;
+
+@Entity
+@Table(name = "entity_type")
+@EntityListeners(AuditingEntityListener.class)
+public class EntityType {
+
+    @Id
+    @Column(nullable = false)
+    private String id;
+
+    @Column(nullable = false)
+    private String externalId;
+
+    @Column(nullable = false)
+    private String name;
+
+    @Column
+    private String description;
+
+    @Column(nullable = false)
+    private long tenantId;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedAt;
+
+    @OneToMany(mappedBy = "entityType", cascade = CascadeType.ALL)
+    private Set<org.apache.custos.sharing.persistance.model.Entity> entitySet;
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLastModifiedAt() {
+        return lastModifiedAt;
+    }
+
+    public void setLastModifiedAt(Date lastModifiedAt) {
+        this.lastModifiedAt = lastModifiedAt;
+    }
+
+    public Set<org.apache.custos.sharing.persistance.model.Entity> getEntitySet() {
+        return entitySet;
+    }
+
+    public void setEntitySet(Set<org.apache.custos.sharing.persistance.model.Entity> entitySet) {
+        this.entitySet = entitySet;
+    }
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getExternalId() {
+        return externalId;
+    }
+
+    public void setExternalId(String externalId) {
+        this.externalId = externalId;
+    }
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/PermissionType.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/PermissionType.java
new file mode 100644
index 0000000..6326943
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/PermissionType.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.Entity;
+import javax.persistence.*;
+import java.util.Date;
+import java.util.Set;
+
+@Entity
+@Table(name = "permission_type")
+@EntityListeners(AuditingEntityListener.class)
+public class PermissionType {
+
+    @Id
+    @Column(nullable = false)
+    private String id;
+
+    @Column
+    private String externalId;
+
+    @Column(nullable = false)
+    private long tenantId;
+
+    @Column(nullable = false)
+    private String name;
+
+    @Column
+    private String description;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedAt;
+
+    @OneToMany(mappedBy = "permissionType", cascade = CascadeType.ALL)
+    private Set<Sharing> sharingSet;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLastModifiedAt() {
+        return lastModifiedAt;
+    }
+
+    public void setLastModifiedAt(Date lastModifiedAt) {
+        this.lastModifiedAt = lastModifiedAt;
+    }
+
+    public Set<Sharing> getSharingSet() {
+        return sharingSet;
+    }
+
+    public void setSharingSet(Set<Sharing> sharingSet) {
+        this.sharingSet = sharingSet;
+    }
+
+    public String getExternalId() {
+        return externalId;
+    }
+
+    public void setExternalId(String externalId) {
+        this.externalId = externalId;
+    }
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Sharing.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Sharing.java
new file mode 100644
index 0000000..566da2e
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Sharing.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.Entity;
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "sharing")
+@EntityListeners(AuditingEntityListener.class)
+public class Sharing {
+
+    @Id
+    private String id;
+
+    @Column(nullable = false)
+    private String associatingId;
+
+    @Column(nullable = false)
+    private String associatingIdType;
+
+    @Column(nullable = false)
+    private String sharingType;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedAt;
+
+
+    @Column(nullable = false)
+    private long tenantId;
+
+
+    @JoinColumn(name = "permission_type_id")
+    @ManyToOne
+    private PermissionType permissionType;
+
+
+    @JoinColumn(name = "entity_id")
+    @ManyToOne
+    private org.apache.custos.sharing.persistance.model.Entity entity;
+
+
+    @JoinColumn(name = "inherited_parent_id")
+    @ManyToOne
+    private org.apache.custos.sharing.persistance.model.Entity inheritedParent;
+
+
+    public String getAssociatingId() {
+        return associatingId;
+    }
+
+    public void setAssociatingId(String associatingId) {
+        this.associatingId = associatingId;
+    }
+
+    public String getSharingType() {
+        return sharingType;
+    }
+
+    public void setSharingType(String sharingType) {
+        this.sharingType = sharingType;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLastModifiedAt() {
+        return lastModifiedAt;
+    }
+
+    public void setLastModifiedAt(Date lastModifiedAt) {
+        this.lastModifiedAt = lastModifiedAt;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public PermissionType getPermissionType() {
+        return permissionType;
+    }
+
+    public void setPermissionType(PermissionType permissionType) {
+        this.permissionType = permissionType;
+    }
+
+    public org.apache.custos.sharing.persistance.model.Entity getEntity() {
+        return entity;
+    }
+
+    public void setEntity(org.apache.custos.sharing.persistance.model.Entity entity) {
+        this.entity = entity;
+    }
+
+    public org.apache.custos.sharing.persistance.model.Entity getInheritedParent() {
+        return inheritedParent;
+    }
+
+    public void setInheritedParent(org.apache.custos.sharing.persistance.model.Entity inheritedParent) {
+        this.inheritedParent = inheritedParent;
+    }
+
+    public String getAssociatingIdType() {
+        return associatingIdType;
+    }
+
+    public void setAssociatingIdType(String associatingIdType) {
+        this.associatingIdType = associatingIdType;
+    }
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/EntityRepository.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/EntityRepository.java
new file mode 100644
index 0000000..f6623fa
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/EntityRepository.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.repository;
+
+import org.apache.custos.sharing.persistance.model.Entity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface EntityRepository  extends JpaRepository<Entity, String>, SearchEntityRepository {
+
+    public List<Entity> findAllByExternalParentIdAndTenantId(String externalParentId, long tenantId);
+
+
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/EntityTypeRepository.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/EntityTypeRepository.java
new file mode 100644
index 0000000..93a2ce6
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/EntityTypeRepository.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.repository;
+
+import org.apache.custos.sharing.persistance.model.EntityType;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface EntityTypeRepository extends JpaRepository<EntityType, String> {
+
+
+    public List<EntityType> findAllByTenantId(long tenantId);
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/PermissionTypeRepository.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/PermissionTypeRepository.java
new file mode 100644
index 0000000..b74df0a
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/PermissionTypeRepository.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.repository;
+
+import org.apache.custos.sharing.persistance.model.PermissionType;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface PermissionTypeRepository extends JpaRepository<org.apache.custos.sharing.persistance.model.PermissionType, String> {
+
+    public List<PermissionType> findAllByTenantId(long tenantId);
+
+    public Optional<PermissionType> findByExternalIdAndTenantId(String externalId, long tenantId);
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java
new file mode 100644
index 0000000..3ae32a8
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.repository;
+
+import org.apache.custos.sharing.persistance.model.Entity;
+import org.apache.custos.sharing.service.SearchCriteria;
+
+import java.util.List;
+
+public interface SearchEntityRepository {
+
+
+    List<Entity> searchEntities(long tenantId, List<SearchCriteria> searchCriteria);
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepositoryImpl.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepositoryImpl.java
new file mode 100644
index 0000000..e185861
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepositoryImpl.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.repository;
+
+import org.apache.custos.sharing.persistance.model.Entity;
+import org.apache.custos.sharing.service.EntitySearchField;
+import org.apache.custos.sharing.service.SearchCondition;
+import org.apache.custos.sharing.service.SearchCriteria;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Repository
+public  class SearchEntityRepositoryImpl implements SearchEntityRepository {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SearchEntityRepositoryImpl.class);
+
+    @PersistenceContext
+    EntityManager entityManager;
+
+    @Override
+    public List<Entity> searchEntities(long tenantId, List<SearchCriteria> searchCriteria) {
+
+        Map<String, Object> valueMap = new HashMap<>();
+        String query = createSQLQuery(tenantId,searchCriteria, valueMap);
+
+
+
+        Query q = entityManager.createNativeQuery(query, Entity.class);
+        for (String key : valueMap.keySet()) {
+            q.setParameter(key, valueMap.get(key));
+        }
+
+        return q.getResultList();
+
+    }
+
+
+    private String createSQLQuery(long tenantId, List<SearchCriteria> searchCriteriaList, Map<String, Object> valueMap) {
+
+        String query = "SELECT * FROM entity E WHERE ";
+
+        for (SearchCriteria searchCriteria : searchCriteriaList) {
+
+            if (searchCriteria.getSearchField().equals(EntitySearchField.ID)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.EQUAL)) {
+                    query = query + "E.external_id = :" + EntitySearchField.ID.name() + " AND ";
+                } else {
+                    query = query + "E.external_id != :" + EntitySearchField.ID.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.ID.name(), searchCriteria.getValue());
+
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.NAME)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.EQUAL)) {
+                    query = query + "E.name LIKE :" + EntitySearchField.NAME.name() + " AND ";
+                } else {
+                    query = query + "E.name NOT LIKE :" + EntitySearchField.NAME.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.NAME.name(), searchCriteria.getValue());
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.DESCRIPTION)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.EQUAL)) {
+                    query = query + "E.description LIKE :" + EntitySearchField.DESCRIPTION.name() + " AND ";
+                } else {
+                    query = query + "E.description NOT LIKE :" + EntitySearchField.DESCRIPTION.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.DESCRIPTION.name(), searchCriteria.getValue());
+
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.FULL_TEXT)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.EQUAL)) {
+                    query = query + "E.fullText LIKE :" + EntitySearchField.DESCRIPTION.name() + " AND ";
+                } else {
+                    query = query + "E.fullText NOT LIKE :" + EntitySearchField.DESCRIPTION.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.FULL_TEXT.name(), searchCriteria.getValue());
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.OWNER_ID)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.EQUAL)) {
+                    query = query + "E.owner_id = :" + EntitySearchField.OWNER_ID.name() + " AND ";
+                } else {
+                    query = query + "E.owner_id != :" + EntitySearchField.OWNER_ID.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.OWNER_ID.name(), searchCriteria.getValue());
+
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.ENTITY_TYPE_ID)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.EQUAL)) {
+                    query = query + "E.entity_type_id = :" + EntitySearchField.ENTITY_TYPE_ID.name() + " AND ";
+                } else {
+                    query = query + "E.entity_type_id != :" + EntitySearchField.ENTITY_TYPE_ID.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.ENTITY_TYPE_ID.name(), searchCriteria.getValue()+"@"+tenantId);
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.CREATED_AT)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.GTE)) {
+                    query = query + "E.created_at >= :" + EntitySearchField.CREATED_AT.name() + " AND ";
+                } else {
+                    query = query + "E.created_at < :" + EntitySearchField.CREATED_AT.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.CREATED_AT.name(), searchCriteria.getValue());
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.LAST_MODIFIED_AT)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.GTE)) {
+                    query = query + "E.last_modified_at >= :" + EntitySearchField.ENTITY_TYPE_ID.name() + " AND ";
+                } else {
+                    query = query + "E.last_modified_at < :" + EntitySearchField.ENTITY_TYPE_ID.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.ENTITY_TYPE_ID.name(), searchCriteria.getValue());
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.PARENT_ID)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.EQUAL)) {
+                    query = query + "E.external_parent_id = :" + EntitySearchField.PARENT_ID.name() + " AND ";
+                } else {
+                    query = query + "E.external_parent_id != :" + EntitySearchField.PARENT_ID.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.PARENT_ID.name(), searchCriteria.getValue());
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.SHARED_COUNT)) {
+                if (searchCriteria.getCondition().equals(SearchCondition.GTE)) {
+                    query = query + "E.shared_count >= :" + EntitySearchField.SHARED_COUNT.name() + " AND ";
+                } else {
+                    query = query + "E.shared_count < :" + EntitySearchField.SHARED_COUNT.name() + " AND ";
+                }
+                valueMap.put(EntitySearchField.SHARED_COUNT.name(), searchCriteria.getValue());
+            }
+
+        }
+        query = query.substring(0, query.length() - 5);
+
+        query = query + " ORDER BY E.created_at DESC";
+
+        return query;
+    }
+
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SharingRepository.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SharingRepository.java
new file mode 100644
index 0000000..9fd258b
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SharingRepository.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.persistance.repository;
+
+import org.apache.custos.sharing.persistance.model.Sharing;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+public interface SharingRepository extends JpaRepository<Sharing, String> {
+
+    @Query(value = "select * from sharing s where s.tenant_id = ?1 and s.entity_id = ?2 " +
+            "and s.sharing_type IN  ?3", nativeQuery = true)
+    public List<Sharing> findSharingForEntityOfTenant(long tenantId, String entityId, List<String> sharingTypes);
+
+    @Modifying
+    @Transactional
+    @Query(value = "delete  from sharing s where s.tenant_id = ?1 and s.entity_id = ?2 " +
+            "and s.sharing_type = ?3", nativeQuery = true)
+    public void removeGivenCascadingPermissionsForEntity(long tenantId, String entityId, String sharingType);
+
+
+    @Query(value = "select * from sharing s where s.tenant_id = ?1 and s.entity_id = ?2 " +
+            "and s.permission_type_id = ?3 and s.sharing_type IN ?4", nativeQuery = true)
+    public List<Sharing> findAllByEntityAndSharingTypeAndPermissionType
+            (long tenantId, String entityId, String permissionTypeId, List<String> sharingTypes);
+
+
+    @Query(value = "select * from sharing s where s.tenant_id = ?1 and s.entity_id = ?2 " +
+            "and s.permission_type_id = ?3 and s.associating_id_type = ?4", nativeQuery = true)
+    public List<Sharing> findAllByEntityAndPermissionTypeAndOwnerType
+            (long tenantId, String entityId, String permissionTypeId, String associatingIdType);
+
+    @Query(value = "select * from sharing s where s.tenant_id = ?1 and s.entity_id = ?2 " +
+            "and s.permission_type_id = ?3 and s.associating_id_type = ?4 and s.sharing_type IN ?5", nativeQuery = true)
+    public List<Sharing> findAllByEntityAndPermissionTypeAndOwnerTypeAndSharingType
+            (long tenantId, String entityId, String permissionTypeId, String associatingIdType, List<String> sharingList);
+
+
+
+    @Transactional
+    public List<Sharing> deleteAllByInheritedParentIdAndPermissionTypeIdAndTenantIdAndSharingTypeAndAssociatingId(
+            String inheritedParentId, String permissionTypeId, long tenantId, String sharingType, String associatedId);
+
+
+    @Transactional
+    public void deleteAllByEntityIdAndPermissionTypeIdAndAssociatingIdAndTenantIdAndInheritedParentId(
+            String entityId, String permissionTypeId, String associatingId, long tenantId, String inheritedParentId);
+
+    @Query(value = "select * from sharing s where s.tenant_id = ?1 and s.entity_id = ?2 " +
+            "and s.permission_type_id IN ?3 and s.associating_id IN  ?4", nativeQuery = true)
+    public List<Sharing>  findAllSharingOfEntityForGroupsUnderPermissions(long tenantId, String entityId,
+                                                                          List<String> permissionTypes,
+                                                                          List<String> associatedIds);
+
+
+    @Query(value = "select * from sharing s where s.tenant_id = ?1 and s.associating_id IN  ?2 " +
+            "and s.entity_id  IN ?3", nativeQuery = true)
+    public List<Sharing>  findAllSharingEntitiesForUsers(long tenantId,
+                                                                          List<String> associatedIds,
+                                                                          List<String> entityIds);
+
+
+
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/service/SharingService.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/service/SharingService.java
new file mode 100644
index 0000000..18f7b4f
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/service/SharingService.java
@@ -0,0 +1,1412 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.service;
+
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.sharing.mapper.EntityMapper;
+import org.apache.custos.sharing.mapper.EntityTypeMapper;
+import org.apache.custos.sharing.mapper.PermissionTypeMapper;
+import org.apache.custos.sharing.mapper.SharingMapper;
+import org.apache.custos.sharing.persistance.model.Sharing;
+import org.apache.custos.sharing.persistance.repository.EntityRepository;
+import org.apache.custos.sharing.persistance.repository.EntityTypeRepository;
+import org.apache.custos.sharing.persistance.repository.PermissionTypeRepository;
+import org.apache.custos.sharing.persistance.repository.SharingRepository;
+import org.apache.custos.sharing.utils.Constants;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Optional;
+
+@GRpcService
+public class SharingService extends org.apache.custos.sharing.service.SharingServiceGrpc.SharingServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SharingService.class);
+
+    @Autowired
+    private EntityRepository entityRepository;
+
+    @Autowired
+    private EntityTypeRepository entityTypeRepository;
+
+    @Autowired
+    private PermissionTypeRepository permissionTypeRepository;
+
+    @Autowired
+    private SharingRepository sharingRepository;
+
+
+    @Override
+    public void createEntityType(org.apache.custos.sharing.service.EntityTypeRequest request,
+                                 StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createEntityType for" + request.getEntityType().getId() +
+                    " in" + request.getTenantId());
+
+            String internalId = request.getEntityType().getId() + "@" + request.getTenantId();
+
+            Optional<org.apache.custos.sharing.persistance.model.EntityType> optionalEntityType =
+                    entityTypeRepository.findById(internalId);
+
+            if (optionalEntityType.isPresent()) {
+                String msg = "Entity type  id" + request.getEntityType().getId() + "is already present";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.ALREADY_EXISTS.asRuntimeException());
+                return;
+            }
+
+            org.apache.custos.sharing.persistance.model.EntityType
+                    type = EntityTypeMapper.createEntityType(request.getEntityType(), request.getTenantId());
+            entityTypeRepository.save(type);
+
+            org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                    .newBuilder()
+                    .setStatus(true)
+                    .build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while creating entity type for " + request.getEntityType().getId() +
+                    " in" + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void updateEntityType(org.apache.custos.sharing.service.EntityTypeRequest request,
+                                 StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateEntityType for " + request.getEntityType().getId() +
+                    "in " + request.getTenantId());
+            String internalId = request.getEntityType().getId() + "@" + request.getTenantId();
+
+            Optional<org.apache.custos.sharing.persistance.model.EntityType> optionalEntityType =
+                    entityTypeRepository.findById(internalId);
+
+            if (optionalEntityType.isEmpty()) {
+                String msg = "Entity type  id" + request.getEntityType().getId() + "is not present";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.INTERNAL.asRuntimeException());
+                return;
+            }
+
+
+            org.apache.custos.sharing.persistance.model.EntityType
+                    type = EntityTypeMapper.createEntityType(request.getEntityType(), request.getTenantId());
+
+            type.setCreatedAt(optionalEntityType.get().getCreatedAt());
+
+            entityTypeRepository.save(type);
+
+            org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                    .newBuilder()
+                    .setStatus(true)
+                    .build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while updating entity type" + request.getEntityType().getId()
+                    + "in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void deleteEntityType(org.apache.custos.sharing.service.EntityTypeRequest request,
+                                 StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteEntityType for" + request.getEntityType().getId()
+                    + "in " + request.getTenantId());
+            String internalId = request.getEntityType().getId() + "@" + request.getTenantId();
+            Optional<org.apache.custos.sharing.persistance.model.EntityType> optionalEntityType =
+                    entityTypeRepository.findById(internalId);
+
+            if (optionalEntityType.isEmpty()) {
+                String msg = "Entity type  id" + request.getEntityType().getId() + "is not present";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.INTERNAL.asRuntimeException());
+                return;
+            }
+
+            entityTypeRepository.delete(optionalEntityType.get());
+
+            org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                    .newBuilder()
+                    .setStatus(true)
+                    .build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting entity type" + request.getEntityType().getId()
+                    + "in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getEntityType(org.apache.custos.sharing.service.EntityTypeRequest request,
+                              StreamObserver<org.apache.custos.sharing.service.EntityType> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getEntityType for " + request.getEntityType().getId() +
+                    " in " + request.getTenantId());
+
+            String internalId = request.getEntityType().getId() + "@" + request.getTenantId();
+            Optional<org.apache.custos.sharing.persistance.model.EntityType> optionalEntityType =
+                    entityTypeRepository.findById(internalId);
+
+
+            if (optionalEntityType.isPresent()) {
+                org.apache.custos.sharing.service.EntityType type =
+                        EntityTypeMapper.createEntityType(optionalEntityType.get());
+                responseObserver.onNext(type);
+                responseObserver.onCompleted();
+
+            } else {
+                org.apache.custos.sharing.service.EntityType type =
+                        org.apache.custos.sharing.service.EntityType.newBuilder().build();
+                responseObserver.onNext(type);
+                responseObserver.onCompleted();
+
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching entity type for " + request.getEntityType().getId() +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getEntityTypes(org.apache.custos.sharing.service.SearchRequest request,
+                               StreamObserver<org.apache.custos.sharing.service.EntityTypes> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getEntityTypes " + " in " + request.getTenantId());
+
+            List<org.apache.custos.sharing.persistance.model.EntityType> types =
+                    entityTypeRepository.findAllByTenantId(request.getTenantId());
+
+            List<org.apache.custos.sharing.service.EntityType> entityTypes = new ArrayList<>();
+
+            if (!types.isEmpty()) {
+
+                for (org.apache.custos.sharing.persistance.model.EntityType type : types) {
+
+                    entityTypes.add(EntityTypeMapper.createEntityType(type));
+                }
+
+            }
+
+            org.apache.custos.sharing.service.EntityTypes entityTy = org.apache.custos.sharing.service.EntityTypes
+                    .newBuilder()
+                    .addAllTypes(entityTypes)
+                    .build();
+
+            responseObserver.onNext(entityTy);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching entity types  in "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void createPermissionType(org.apache.custos.sharing.service.PermissionTypeRequest request,
+                                     StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createPermissionType with id " + request.getPermissionType().getId()
+                    + " in " + request.getTenantId());
+
+            String internalId = request.getPermissionType().getId() + "@" + request.getTenantId();
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalEntityType =
+                    permissionTypeRepository.findById(internalId);
+
+            if (optionalEntityType.isPresent()) {
+                String msg = "Permission type  id" + request.getPermissionType().getId() + "is already present";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.ALREADY_EXISTS.asRuntimeException());
+                return;
+            }
+
+            org.apache.custos.sharing.persistance.model.PermissionType
+                    type = PermissionTypeMapper.createPermissionType(request.getPermissionType(), request.getTenantId());
+            permissionTypeRepository.save(type);
+
+            org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                    .newBuilder()
+                    .setStatus(true)
+                    .build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while creating permission type with id " + request.getPermissionType().getId()
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void updatePermissionType(org.apache.custos.sharing.service.PermissionTypeRequest request,
+                                     StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updatePermissionType with id " + request.getPermissionType().getId()
+                    + " in " + request.getTenantId());
+
+            String internalId = request.getPermissionType().getId() + "@" + request.getTenantId();
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalEntityType =
+                    permissionTypeRepository.findById(internalId);
+
+            if (optionalEntityType.isEmpty()) {
+                String msg = "Entity type  id" + request.getPermissionType().getId() + "is not present";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.INTERNAL.asRuntimeException());
+                return;
+            }
+
+            org.apache.custos.sharing.persistance.model.PermissionType
+                    type = PermissionTypeMapper.createPermissionType(request.getPermissionType(), request.getTenantId());
+
+            type.setCreatedAt(optionalEntityType.get().getCreatedAt());
+
+            permissionTypeRepository.save(type);
+
+            org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                    .newBuilder()
+                    .setStatus(true)
+                    .build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while updating permission type with id " + request.getPermissionType().getId()
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deletePermissionType(org.apache.custos.sharing.service.PermissionTypeRequest request,
+                                     StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deletePermissionType with id " + request.getPermissionType().getId()
+                    + " in " + request.getTenantId());
+            String internalId = request.getPermissionType().getId() + "@" + request.getTenantId();
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalEntityType =
+                    permissionTypeRepository.findById(internalId);
+
+            if (optionalEntityType.isEmpty()) {
+                String msg = "Entity type  id" + request.getPermissionType().getId() + "is not present";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.INTERNAL.asRuntimeException());
+                return;
+            }
+
+            permissionTypeRepository.delete(optionalEntityType.get());
+
+            org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                    .newBuilder()
+                    .setStatus(true)
+                    .build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting permission type with id " + request.getPermissionType().getId()
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getPermissionType(org.apache.custos.sharing.service.PermissionTypeRequest request,
+                                  StreamObserver<org.apache.custos.sharing.service.PermissionType> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getPermissionType with id " + request.getPermissionType().getId()
+                    + " in " + request.getTenantId());
+
+            String internalId = request.getPermissionType().getId() + "@" + request.getTenantId();
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalEntityType =
+                    permissionTypeRepository.findById(internalId);
+
+
+            if (optionalEntityType.isPresent()) {
+                org.apache.custos.sharing.service.PermissionType type =
+                        PermissionTypeMapper.createPermissionType(optionalEntityType.get());
+                responseObserver.onNext(type);
+                responseObserver.onCompleted();
+
+            } else {
+                org.apache.custos.sharing.service.PermissionType type =
+                        org.apache.custos.sharing.service.PermissionType.newBuilder().build();
+                responseObserver.onNext(type);
+                responseObserver.onCompleted();
+
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching permission type with id " + request.getPermissionType().getId()
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getPermissionTypes(org.apache.custos.sharing.service.SearchRequest request,
+                                   StreamObserver<org.apache.custos.sharing.service.PermissionTypes> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getPermissionTypes " + " in " + request.getTenantId());
+
+            List<org.apache.custos.sharing.persistance.model.PermissionType> types =
+                    permissionTypeRepository.findAllByTenantId(request.getTenantId());
+
+            List<org.apache.custos.sharing.service.PermissionType> entityTypes = new ArrayList<>();
+
+            if (!types.isEmpty()) {
+
+                for (org.apache.custos.sharing.persistance.model.PermissionType type : types) {
+
+                    entityTypes.add(PermissionTypeMapper.createPermissionType(type));
+                }
+
+            }
+
+            org.apache.custos.sharing.service.PermissionTypes entityTy = org.apache.custos.sharing.service.PermissionTypes
+                    .newBuilder()
+                    .addAllTypes(entityTypes)
+                    .build();
+
+            responseObserver.onNext(entityTy);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching permission types"
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void createEntity(org.apache.custos.sharing.service.EntityRequest request,
+                             StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createEntity with id" + request.getEntity().getId() + " in "
+                    + request.getTenantId());
+
+
+            org.apache.custos.sharing.service.Entity entity = request.getEntity();
+
+            long tenantId = request.getTenantId();
+
+            String entityTypeId = entity.getType() + "@" + tenantId;
+
+            String internalParentId = null;
+
+            if (entity.getParentId() != null && !entity.getParentId().trim().equals("")) {
+
+                internalParentId = entity.getParentId() + "@" + tenantId;
+
+
+                Optional<org.apache.custos.sharing.persistance.model.Entity> optionalEntity = entityRepository.
+                        findById(internalParentId);
+
+                if (optionalEntity.isEmpty()) {
+                    String msg = "Cannot find a parent Entity  with given Id " + entity.getParentId();
+                    LOGGER.error(msg);
+                    responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                    return;
+                }
+
+            }
+
+            Optional<org.apache.custos.sharing.persistance.model.EntityType> entityType =
+                    entityTypeRepository.findById(entityTypeId);
+
+            if (entityType.isEmpty()) {
+                String msg = "Cannot find a Entity Type with given Id " + entity.getId();
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            org.apache.custos.sharing.persistance.model.Entity enModel =
+                    EntityMapper.createEntity(entity, tenantId, entityType.get());
+
+            org.apache.custos.sharing.persistance.model.Entity savedEntity = entityRepository.save(enModel);
+
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalPermissionType =
+                    permissionTypeRepository.findByExternalIdAndTenantId(Constants.OWNER, tenantId);
+
+            if (optionalPermissionType.isPresent()) {
+                Sharing sharing = SharingMapper.createSharing(optionalPermissionType.get(),
+                        savedEntity, savedEntity, entity.getOwnerId(), Constants.USER, Constants.DIRECT_CASCADING, tenantId);
+
+                sharingRepository.save(sharing);
+
+            }
+
+            if (internalParentId != null) {
+                addCascadingPermissionForEntity(savedEntity, internalParentId, tenantId);
+
+            }
+
+
+            List<String> sharingType = new ArrayList<>();
+            sharingType.add(Constants.INDIRECT_CASCADING);
+            List<Sharing> sharings = sharingRepository.findAllByEntityAndSharingTypeAndPermissionType(tenantId,
+                    enModel.getId(),
+                    optionalPermissionType.get().getId(), sharingType);
+
+
+            if (sharings != null && sharings.size() > 0) {
+                savedEntity.setSharedCount(sharings.size());
+                entityRepository.save(savedEntity);
+            }
+
+
+            org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                    .newBuilder()
+                    .setStatus(true)
+                    .build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while creating Entity with id " + request.getEntity().getId()
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void updateEntity(org.apache.custos.sharing.service.EntityRequest request,
+                             StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateEntity with id" + request.getEntity().getId() + " in "
+                    + request.getTenantId());
+
+            org.apache.custos.sharing.service.Entity entity = request.getEntity();
+
+            long tenantId = request.getTenantId();
+
+            String entityTypeId = entity.getType() + "@" + tenantId;
+
+            String internalEntityId = entity.getId() + "@" + tenantId;
+
+            Optional<org.apache.custos.sharing.persistance.model.Entity> optionalEntity = entityRepository.findById(internalEntityId);
+
+            if (optionalEntity.isEmpty()) {
+                String msg = "Cannot find a Entity  with given Id " + entity.getId();
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            Optional<org.apache.custos.sharing.persistance.model.EntityType> entityType =
+                    entityTypeRepository.findById(entityTypeId);
+
+            if (entityType.isEmpty()) {
+                String msg = "Cannot find a Entity Type with given Id " + entity.getType();
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            org.apache.custos.sharing.persistance.model.Entity oldEntity = optionalEntity.get();
+
+            org.apache.custos.sharing.persistance.model.Entity newEntity =
+                    EntityMapper.createEntity(entity, tenantId, entityType.get());
+
+            if (!oldEntity.getOwnerId().equals(newEntity.getOwnerId())) {
+                String msg = "Entity owner cannot change ";
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalPermissionType =
+                    permissionTypeRepository.findByExternalIdAndTenantId(Constants.OWNER, tenantId);
+
+
+            if (oldEntity.getExternalParentId() != null &&
+                    !oldEntity.getExternalParentId().equals(newEntity.getExternalParentId())) {
+
+                sharingRepository.removeGivenCascadingPermissionsForEntity(tenantId, internalEntityId, Constants.INDIRECT_CASCADING);
+
+            }
+
+
+            if (newEntity.getExternalParentId() != null) {
+                String internalParentId = newEntity.getExternalParentId() + "@" + tenantId;
+                addCascadingPermissionForEntity(newEntity, internalParentId, tenantId);
+
+            }
+            List<String> sharingType = new ArrayList<>();
+            sharingType.add(Constants.INDIRECT_CASCADING);
+
+            List<Sharing> sharings = sharingRepository.findAllByEntityAndSharingTypeAndPermissionType(tenantId,
+                    internalEntityId, optionalPermissionType.get().getId(), sharingType);
+
+            if (sharings != null && sharings.size() > 0) {
+                newEntity.setSharedCount(sharings.size());
+            }
+
+            newEntity.setCreatedAt(oldEntity.getCreatedAt());
+
+            entityRepository.save(newEntity);
+
+            org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                    .newBuilder()
+                    .setStatus(true)
+                    .build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while updating Entity with id " + request.getEntity().getId()
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void isEntityExists(org.apache.custos.sharing.service.EntityRequest request,
+                               StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to isEntityExists with id" + request.getEntity().getId() + " in "
+                    + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+
+            String entityId = request.getEntity().getId();
+
+            String internalId = entityId + "@" + tenantId;
+
+
+            Optional<org.apache.custos.sharing.persistance.model.Entity> optionalEntity =
+                    entityRepository.findById(internalId);
+
+            if (optionalEntity.isEmpty()) {
+                org.apache.custos.sharing.service.Status status =
+                        org.apache.custos.sharing.service.Status.newBuilder().setStatus(false).build();
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+            } else {
+                org.apache.custos.sharing.service.Status status =
+                        org.apache.custos.sharing.service.Status.newBuilder().setStatus(true).build();
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while checking isEntityExists with id " + request.getEntity().getId()
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+
+    }
+
+    @Override
+    public void getEntity(org.apache.custos.sharing.service.EntityRequest request,
+                          StreamObserver<org.apache.custos.sharing.service.Entity> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getEntity with id" + request.getEntity().getId() + " in "
+                    + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+
+            String entityId = request.getEntity().getId();
+
+            String internalId = entityId + "@" + tenantId;
+
+
+            Optional<org.apache.custos.sharing.persistance.model.Entity> optionalEntity =
+                    entityRepository.findById(internalId);
+
+            if (optionalEntity.isEmpty()) {
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.
+                        withDescription("Entity not found for id " + entityId).asRuntimeException());
+            } else {
+                responseObserver.onNext(EntityMapper.createEntity(optionalEntity.get()));
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching Entity with id " + request.getEntity().getId()
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteEntity(org.apache.custos.sharing.service.EntityRequest request,
+                             StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteEntity with id" + request.getEntity().getId() + " in "
+                    + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+
+            String entityId = request.getEntity().getId();
+
+            String internalId = entityId + "@" + tenantId;
+
+            Optional<org.apache.custos.sharing.persistance.model.Entity> optionalEntity =
+                    entityRepository.findById(internalId);
+
+
+            if (optionalEntity.isPresent()) {
+                entityRepository.delete(optionalEntity.get());
+            }
+
+            org.apache.custos.sharing.service.Status status =
+                    org.apache.custos.sharing.service.Status.newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting Entity with id " + request.getEntity().getId()
+                    + " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void searchEntities(org.apache.custos.sharing.service.SearchRequest request,
+                               StreamObserver<org.apache.custos.sharing.service.Entities> responseObserver) {
+        try {
+            LOGGER.debug("Request received to search entities in tenant"
+                    + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+
+            List<org.apache.custos.sharing.persistance.model.Entity> entities = entityRepository.
+                    searchEntities(tenantId, request.getSearchCriteriaList());
+
+            HashMap<String, org.apache.custos.sharing.service.Entity> entryMap = new HashMap<>();
+
+
+            List<String> internalEntityIds = new ArrayList<>();
+
+            if (entities != null && !entities.isEmpty()) {
+
+                for (org.apache.custos.sharing.persistance.model.Entity entity : entities) {
+                    internalEntityIds.add(entity.getId());
+                }
+
+                List<Sharing> sharings = sharingRepository.
+                        findAllSharingEntitiesForUsers(tenantId, request.getAssociatingIdsList(), internalEntityIds);
+                if (sharings != null && !sharings.isEmpty()) {
+                    for (Sharing sharing : sharings) {
+                        Entity entity = EntityMapper.createEntity(sharing.getEntity());
+                        entryMap.put(entity.getId(), entity);
+
+                    }
+                }
+            }
+            List<org.apache.custos.sharing.service.Entity> entityList = new ArrayList<>(entryMap.values());
+            org.apache.custos.sharing.service.Entities resp = org.apache.custos.sharing.service.Entities
+                    .newBuilder()
+                    .addAllEntityArray(entityList)
+                    .build();
+            responseObserver.onNext(resp);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while search entities with id " +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getListOfSharedUsers(org.apache.custos.sharing.service.SharingRequest request,
+                                     StreamObserver<org.apache.custos.sharing.service.SharedOwners> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getListOfSharedUsers " + request.getTenantId() + " for entity "
+                    + request.getEntity().getId());
+
+            long tenantId = request.getTenantId();
+
+            String entityId = request.getEntity().getId();
+
+            String internalEntityId = entityId + "@" + tenantId;
+
+            String permisstionType = request.getPermissionType().getId();
+
+            String internalPermissionTypeId = request.getPermissionType().getId() + "@" + tenantId;
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> permissionType =
+                    permissionTypeRepository.findById(internalPermissionTypeId);
+
+            if (permissionType.isEmpty()) {
+                String msg = "Cannot find permission type" + permisstionType;
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            Optional<org.apache.custos.sharing.persistance.model.Entity> optionalEntity = entityRepository.
+                    findById(internalEntityId);
+
+            if (optionalEntity.isEmpty()) {
+                String msg = "Cannot find given entity" + entityId;
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalPermissionType =
+                    permissionTypeRepository.findByExternalIdAndTenantId(Constants.OWNER, tenantId);
+            List<Sharing> sharings = null;
+            if (optionalPermissionType.get().equals(internalPermissionTypeId)) {
+                List<String> sharingList = new ArrayList<>();
+                sharingList.add(Constants.DIRECT_CASCADING);
+                sharingList.add(Constants.DIRECT_NON_CASCADING);
+
+                sharings = sharingRepository.
+                        findAllByEntityAndPermissionTypeAndOwnerTypeAndSharingType(tenantId, internalEntityId,
+                                internalPermissionTypeId, Constants.USER, sharingList);
+            } else {
+
+                sharings = sharingRepository.
+                        findAllByEntityAndPermissionTypeAndOwnerType(tenantId, internalEntityId,
+                                internalPermissionTypeId, Constants.USER);
+
+            }
+            org.apache.custos.sharing.service.SharedOwners owners = SharingMapper.getSharedOwners(sharings);
+
+            responseObserver.onNext(owners);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching  getListOfSharedUsers  for entity "
+                    + request.getEntity().getId() +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getListOfDirectlySharedUsers(org.apache.custos.sharing.service.SharingRequest request,
+                                             StreamObserver<org.apache.custos.sharing.service.SharedOwners> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getListOfDirectlySharedUsers " + request.getTenantId() + " for entity "
+                    + request.getEntity().getId());
+
+            long tenantId = request.getTenantId();
+
+            String entityId = request.getEntity().getId();
+
+            String internalEntityId = entityId + "@" + tenantId;
+
+            String permissionType = request.getPermissionType().getId();
+
+            String internalPermissionTypeId = request.getPermissionType().getId() + "@" + tenantId;
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> oPT =
+                    permissionTypeRepository.findById(internalPermissionTypeId);
+
+            if (oPT.isEmpty()) {
+                String msg = "Cannot find permission type" + permissionType;
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            Optional<org.apache.custos.sharing.persistance.model.Entity> optionalEntity = entityRepository.
+                    findById(internalEntityId);
+
+            if (optionalEntity.isEmpty()) {
+                String msg = "Cannot find given entity" + entityId;
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            List<String> sharingList = new ArrayList<>();
+            sharingList.add(Constants.DIRECT_CASCADING);
+            sharingList.add(Constants.DIRECT_NON_CASCADING);
+
+            List<Sharing> sharings = sharingRepository.
+                    findAllByEntityAndPermissionTypeAndOwnerTypeAndSharingType(tenantId, internalEntityId,
+                            internalPermissionTypeId, Constants.USER, sharingList);
+            org.apache.custos.sharing.service.SharedOwners owners = SharingMapper.getSharedOwners(sharings);
+
+            responseObserver.onNext(owners);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching  directly shared users  for entity "
+                    + request.getEntity().getId() +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getListOfSharedGroups(org.apache.custos.sharing.service.SharingRequest request,
+                                      StreamObserver<org.apache.custos.sharing.service.SharedOwners> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getListOfSharedGroups " + request.getTenantId() + " for entity "
+                    + request.getEntity().getId());
+            long tenantId = request.getTenantId();
+
+            String entityId = request.getEntity().getId();
+
+            String internalEntityId = entityId + "@" + tenantId;
+
+            String permisstionType = request.getPermissionType().getId();
+
+            String internalPermissionTypeId = request.getPermissionType().getId() + "@" + tenantId;
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> permissionType =
+                    permissionTypeRepository.findById(internalPermissionTypeId);
+
+            if (permissionType.isEmpty()) {
+                String msg = "Cannot find permission type" + permisstionType;
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            Optional<org.apache.custos.sharing.persistance.model.Entity> optionalEntity = entityRepository.
+                    findById(internalEntityId);
+
+            if (optionalEntity.isEmpty()) {
+                String msg = "Cannot find given entity" + entityId;
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            List<Sharing> sharings = sharingRepository.
+                    findAllByEntityAndPermissionTypeAndOwnerType(tenantId, internalEntityId,
+                            internalPermissionTypeId, Constants.GROUP);
+
+            org.apache.custos.sharing.service.SharedOwners owners = SharingMapper.getSharedOwners(sharings);
+
+            responseObserver.onNext(owners);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching   shared groups  for entity "
+                    + request.getEntity().getId() +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getListOfDirectlySharedGroups(org.apache.custos.sharing.service.SharingRequest request,
+                                              StreamObserver<org.apache.custos.sharing.service.SharedOwners> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getListOfDirectlySharedGroups " + request.getTenantId() + " for entity "
+                    + request.getEntity().getId());
+
+            long tenantId = request.getTenantId();
+
+            String entityId = request.getEntity().getId();
+
+            String internalEntityId = entityId + "@" + tenantId;
+
+            String permisstionType = request.getPermissionType().getId();
+
+            String internalPermissionTypeId = request.getPermissionType().getId() + "@" + tenantId;
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> permissionType =
+                    permissionTypeRepository.findById(internalPermissionTypeId);
+
+            if (permissionType.isEmpty()) {
+                String msg = "Cannot find permission type" + permisstionType;
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            Optional<org.apache.custos.sharing.persistance.model.Entity> optionalEntity = entityRepository.
+                    findById(internalEntityId);
+
+            if (optionalEntity.isEmpty()) {
+                String msg = "Cannot find given entity" + entityId;
+                LOGGER.error(msg);
+                responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+                return;
+            }
+
+            List<String> sharingList = new ArrayList<>();
+            sharingList.add(Constants.DIRECT_CASCADING);
+            sharingList.add(Constants.DIRECT_NON_CASCADING);
+
+            List<Sharing> sharings = sharingRepository.
+                    findAllByEntityAndPermissionTypeAndOwnerTypeAndSharingType(tenantId, internalEntityId,
+                            internalPermissionTypeId, Constants.GROUP, sharingList);
+
+            org.apache.custos.sharing.service.SharedOwners owners = SharingMapper.getSharedOwners(sharings);
+
+            responseObserver.onNext(owners);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching   directly shared groups  for entity "
+                    + request.getEntity().getId() +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void shareEntityWithUsers(org.apache.custos.sharing.service.SharingRequest request,
+                                     StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to shareEntityWithUsers " + request.getTenantId() + " for entity "
+                    + request.getEntity().getId());
+
+            shareEntity(request, responseObserver, Constants.USER);
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while sharing   entity with user  for entity "
+                    + request.getEntity().getId() +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void shareEntityWithGroups(org.apache.custos.sharing.service.SharingRequest request,
+                                      StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to shareEntityWithGroups " + request.getTenantId() + " for entity "
+                    + request.getEntity().getId());
+            shareEntity(request, responseObserver, Constants.GROUP);
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while sharing   entity with groups  for entity "
+                    + request.getEntity().getId() +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void revokeEntitySharingFromUsers(org.apache.custos.sharing.service.SharingRequest request,
+                                             StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to revokeEntitySharingFromUsers " + request.getTenantId() + " for entity "
+                    + request.getEntity().getId());
+
+
+            revokePermission(request, responseObserver);
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while revoking   entity from users  for entity "
+                    + request.getEntity().getId() +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void revokeEntitySharingFromGroups(org.apache.custos.sharing.service.SharingRequest request,
+                                              StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to revokeEntitySharingFromGroups " + request.getTenantId() + " for entity "
+                    + request.getEntity().getId());
+            revokePermission(request, responseObserver);
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while revoking   entity from groups  for entity "
+                    + request.getEntity().getId() +
+                    " in " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void userHasAccess(org.apache.custos.sharing.service.SharingRequest request,
+                              StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to userHasAccess in " + request.getTenantId() + " for entity "
+                    + request.getEntity().getId() + " for user " + request.getOwnerId(0));
+
+            long tenantId = request.getTenantId();
+            List<String> owners = request.getOwnerIdList();
+            String permission = request.getPermissionType().getId();
+
+            String entityId = request.getEntity().getId();
+
+            String internalPermissionId = permission + "@" + tenantId;
+
+            String internalEntityId = entityId + "@" + tenantId;
+
+            Optional<org.apache.custos.sharing.persistance.model.PermissionType> permissionType =
+                    permissionTypeRepository.findByExternalIdAndTenantId(Constants.OWNER, tenantId);
+
+            List<String> permissionTypes = new ArrayList<>();
+            permissionTypes.add(internalPermissionId);
+            permissionTypes.add(permissionType.get().getId());
+
+
+            List<Sharing> sharings = sharingRepository.findAllSharingOfEntityForGroupsUnderPermissions(tenantId,
+                    internalEntityId, permissionTypes, owners);
+
+            if (sharings != null && !sharings.isEmpty()) {
+
+                org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                        .newBuilder()
+                        .setStatus(true)
+                        .build();
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+            } else {
+                org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                        .newBuilder()
+                        .setStatus(false)
+                        .build();
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while checking access to  "
+                    + request.getEntity().getId() +
+                    " in " + request.getTenantId() + " for user" + request.getOwnerId(0) +
+                    " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    private boolean addCascadingPermissionForEntity
+            (org.apache.custos.sharing.persistance.model.Entity entity, String internalParentId, long tenantId) {
+        List<String> newSharingTypes = new ArrayList<>();
+        newSharingTypes.add(Constants.DIRECT_CASCADING);
+        newSharingTypes.add(Constants.INDIRECT_CASCADING);
+
+        List<Sharing> sharings = sharingRepository.
+                findSharingForEntityOfTenant(tenantId, internalParentId, newSharingTypes);
+
+        if (sharings != null && !sharings.isEmpty()) {
+
+            LOGGER.info("Sharing s found for entity with Id " + internalParentId);
+            for (Sharing sharing : sharings) {
+                Sharing newShr = SharingMapper.getNewSharing(sharing, tenantId, entity);
+                newShr.setSharingType(Constants.INDIRECT_CASCADING);
+                sharingRepository.save(newShr);
+            }
+        }
+        return true;
+
+    }
+
+
+    private List<Sharing> getAllSharingForChildEntities(org.apache.custos.sharing.persistance.model.Entity entity,
+                                                        org.apache.custos.sharing.persistance.model.Entity inheritedEntity,
+                                                        List<String> userIds,
+                                                        long tenantId,
+                                                        org.apache.custos.sharing.persistance.model.PermissionType permissionType,
+                                                        List<Sharing> sharings,
+                                                        String ownerType,
+                                                        String sharingType) {
+
+        List<org.apache.custos.sharing.persistance.model.Entity> entities =
+                entityRepository.findAllByExternalParentIdAndTenantId(entity.getExternalId(), tenantId);
+
+
+        if (entities != null && !entities.isEmpty()) {
+            for (org.apache.custos.sharing.persistance.model.Entity child : entities) {
+                for (String userId : userIds) {
+                    Sharing sharing = SharingMapper.createSharing(permissionType,
+                            child, inheritedEntity, userId, ownerType, sharingType, tenantId);
+                    sharings.add(sharing);
+                }
+                getAllSharingForChildEntities(child, inheritedEntity, userIds, tenantId, permissionType, sharings, ownerType, sharingType);
+
+            }
+            return sharings;
+        }
+        return sharings;
+    }
+
+
+    private void shareEntity(org.apache.custos.sharing.service.SharingRequest request,
+                             StreamObserver<org.apache.custos.sharing.service.Status> responseObserver, String ownerType) {
+        long tenantId = request.getTenantId();
+
+        List<String> userIds = request.getOwnerIdList();
+
+        String permissionType = request.getPermissionType().getId();
+
+        String internalPermissionId = permissionType + "@" + tenantId;
+
+        boolean cascade = request.getCascade();
+
+        String entityId = request.getEntity().getId();
+
+        String internalEntityId = entityId + "@" + tenantId;
+
+
+        Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalPermissionType =
+                permissionTypeRepository.findById(internalPermissionId);
+
+        if (optionalPermissionType.isEmpty()) {
+            String msg = "Permission type not found";
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            return;
+        }
+
+        Optional<org.apache.custos.sharing.persistance.model.Entity> entityOptional =
+                entityRepository.findById(internalEntityId);
+
+        if (entityOptional.isEmpty()) {
+            String msg = " Entity with Id " + entityId + "  not found";
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            return;
+        }
+
+
+        Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalOwnerPermissionType =
+                permissionTypeRepository.findByExternalIdAndTenantId(Constants.OWNER, tenantId);
+
+        if (optionalOwnerPermissionType.get().equals(internalPermissionId)) {
+            String msg = "Owner permission type can not be assigned";
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.PERMISSION_DENIED.withDescription(msg).asRuntimeException());
+            return;
+        }
+
+        String sharingType = null;
+        List<Sharing> sharings = new ArrayList<>();
+
+        if (cascade) {
+            sharingType = Constants.DIRECT_CASCADING;
+        } else {
+            sharingType = Constants.DIRECT_NON_CASCADING;
+        }
+
+
+        for (String userId : userIds) {
+
+            Sharing sharing = SharingMapper.createSharing(optionalPermissionType.get(),
+                    entityOptional.get(), entityOptional.get(), userId, ownerType, sharingType, tenantId);
+            sharings.add(sharing);
+        }
+
+        if (cascade) {
+            List<Sharing> childSharings = new ArrayList<>();
+            childSharings = getAllSharingForChildEntities(entityOptional.get(), entityOptional.get(), userIds, tenantId,
+                    optionalPermissionType.get(), childSharings, ownerType, Constants.INDIRECT_CASCADING);
+            if (!childSharings.isEmpty()) {
+                sharings.addAll(childSharings);
+            }
+        }
+
+
+        List<Sharing> effectiveSharings = new ArrayList<>();
+        if (!sharings.isEmpty()) {
+            sharings.forEach(shr -> {
+                Optional<Sharing> sharing = sharingRepository.findById(shr.getId());
+                if (sharing.isEmpty()) {
+                    effectiveSharings.add(shr);
+                }
+
+            });
+
+        }
+
+
+        if (!effectiveSharings.isEmpty()) {
+            sharingRepository.saveAll(effectiveSharings);
+
+
+            List<String> checkTypes = new ArrayList<>();
+            checkTypes.add(Constants.INDIRECT_CASCADING);
+
+            List<Sharing> newSharings = sharingRepository.findAllByEntityAndSharingTypeAndPermissionType(tenantId,
+                    internalEntityId, optionalPermissionType.get().getId(), checkTypes);
+            org.apache.custos.sharing.persistance.model.Entity entity = entityOptional.get();
+            if (newSharings != null && newSharings.size() > 0) {
+                entity.setSharedCount(newSharings.size());
+            }
+
+            entityRepository.save(entity);
+        }
+
+        org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                .newBuilder()
+                .setStatus(true)
+                .build();
+        responseObserver.onNext(status);
+        responseObserver.onCompleted();
+
+
+    }
+
+    private void revokePermission(org.apache.custos.sharing.service.SharingRequest request,
+                                  StreamObserver<org.apache.custos.sharing.service.Status> responseObserver) {
+        long tenantId = request.getTenantId();
+
+        String entityId = request.getEntity().getId();
+
+        String internalEntityId = entityId + "@" + tenantId;
+
+        String permissionType = request.getPermissionType().getId();
+
+        String internalPermissionType = permissionType + "@" + tenantId;
+
+        List<String> usersList = request.getOwnerIdList();
+
+        Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalPermissionType =
+                permissionTypeRepository.findById(internalPermissionType);
+
+        if (optionalPermissionType.isEmpty()) {
+            String msg = "Permission type not found";
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            return;
+        }
+
+        Optional<org.apache.custos.sharing.persistance.model.Entity> entityOptional =
+                entityRepository.findById(internalEntityId);
+
+        if (entityOptional.isEmpty()) {
+            String msg = " Entity with Id " + entityId + "  not found";
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            return;
+        }
+
+
+        Optional<org.apache.custos.sharing.persistance.model.PermissionType> optionalOwnerPermissionType =
+                permissionTypeRepository.findByExternalIdAndTenantId(Constants.OWNER, tenantId);
+
+        if (optionalOwnerPermissionType.get().equals(internalPermissionType)) {
+            String msg = "Owner permission type can not be assigned";
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.PERMISSION_DENIED.withDescription(msg).asRuntimeException());
+            return;
+        }
+
+
+        for (String userId : usersList) {
+
+            LOGGER.info("deleting " + userId + ":" + internalEntityId + ":" + internalPermissionType + ":" + tenantId);
+            sharingRepository.
+                    deleteAllByEntityIdAndPermissionTypeIdAndAssociatingIdAndTenantIdAndInheritedParentId(
+                            internalEntityId,
+                            internalPermissionType,
+                            userId,
+                            tenantId,
+                            internalEntityId);
+            sharingRepository.deleteAllByInheritedParentIdAndPermissionTypeIdAndTenantIdAndSharingTypeAndAssociatingId(
+                    internalEntityId,
+                    internalPermissionType,
+                    tenantId,
+                    Constants.INDIRECT_CASCADING,
+                    userId);
+        }
+
+
+        List<String> checkTypes = new ArrayList<>();
+        checkTypes.add(Constants.INDIRECT_CASCADING);
+
+        List<Sharing> newSharings = sharingRepository.findAllByEntityAndSharingTypeAndPermissionType(tenantId,
+                internalEntityId, optionalPermissionType.get().getId(), checkTypes);
+        org.apache.custos.sharing.persistance.model.Entity entity = entityOptional.get();
+        if (newSharings != null && newSharings.size() > 0) {
+            entity.setSharedCount(newSharings.size());
+        }
+
+        entityRepository.save(entity);
+
+        org.apache.custos.sharing.service.Status status = org.apache.custos.sharing.service.Status
+                .newBuilder()
+                .setStatus(true)
+                .build();
+        responseObserver.onNext(status);
+        responseObserver.onCompleted();
+    }
+
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/utils/Constants.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/utils/Constants.java
new file mode 100644
index 0000000..efa76ea
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/utils/Constants.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.utils;
+
+public class Constants {
+
+    public static final String OWNER = "OWNER";
+
+    public static final String DIRECT_CASCADING = "DIRECT_CASCADING";
+    public static final String INDIRECT_CASCADING = "INDIRECT_CASCADING";
+    public static final String DIRECT_NON_CASCADING = "DIRECT_NON_CASCADING";
+
+    public static final String USER = "user";
+    public static final String GROUP = "group";
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/validator/InputValidator.java b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/validator/InputValidator.java
new file mode 100644
index 0000000..e5ea4aa
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/validator/InputValidator.java
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.validator;
+
+
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.core.services.commons.exceptions.MissingParameterException;
+import org.apache.custos.sharing.service.*;
+import org.apache.custos.sharing.service.EntityRequest;
+import org.apache.custos.sharing.service.EntityTypeRequest;
+import org.apache.custos.sharing.service.PermissionTypeRequest;
+import org.apache.custos.sharing.service.SearchRequest;
+import org.apache.custos.sharing.service.SharingRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class validates the  request parameter
+ */
+public class InputValidator implements Validator {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "createEntityType":
+            case "updateEntityType":
+                validateEntityTypeRequest(obj, methodName);
+                break;
+            case "deleteEntityType":
+            case "getEntityType":
+                validateEntityTypeIdentifyingRequest(obj, methodName);
+                break;
+            case "getEntityTypes":
+                validateTenantIdOnly(obj, methodName);
+                break;
+            case "createPermissionType":
+            case "updatePermissionType":
+            case "deletePermissionType":
+            case "getPermissionType":
+                validateCreatePermissionTypeRequest(obj, methodName);
+                break;
+            case "getPermissionTypes":
+                validateTenantIdOnly(obj, methodName);
+                break;
+            case "createEntity":
+            case "updateEntity":
+                validateEntityRequest(obj, methodName);
+                break;
+            case "isEntityExists":
+            case "getEntity":
+            case "deleteEntity":
+                validateEntityIdentifierRequest(obj, methodName);
+                break;
+            case "searchEntities":
+                validateSearchEntityRequest(obj, methodName);
+                break;
+            case "getListOfSharedUsers":
+            case "getListOfDirectlySharedUsers":
+            case "getListOfSharedGroups":
+            case "getListOfDirectlySharedGroups":
+                validateGetSharingRequest(obj, methodName);
+                break;
+
+            case "shareEntityWithUsers":
+            case "shareEntityWithGroups":
+            case "revokeEntitySharingFromUsers":
+            case "revokeEntitySharingFromGroups":
+                validateSharingRequest(obj, methodName);
+                break;
+
+            case "userHasAccess":
+                validateCheckAccessRequest(obj, methodName);
+                break;
+            default:
+                throw new RuntimeException("Method not implemented");
+        }
+
+    }
+
+    private boolean validateEntityTypeRequest(Object obj, String methodName) {
+        if (obj instanceof EntityTypeRequest) {
+            EntityTypeRequest entityTypeRequest = (EntityTypeRequest) obj;
+            if (entityTypeRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+            if (entityTypeRequest.getEntityType() == null) {
+                throw new MissingParameterException("Entity type not found", null);
+            }
+            if (entityTypeRequest.getEntityType().getId() == null || entityTypeRequest.
+                    getEntityType().getId().trim().equals("")) {
+                throw new MissingParameterException("Entity type id not found", null);
+            }
+            if (entityTypeRequest.getEntityType().getName() == null || entityTypeRequest.
+                    getEntityType().getName().trim().equals("")) {
+                throw new MissingParameterException("Entity type name not found", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateEntityTypeIdentifyingRequest(Object obj, String methodName) {
+        if (obj instanceof EntityTypeRequest) {
+            EntityTypeRequest entityTypeRequest = (EntityTypeRequest) obj;
+            if (entityTypeRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+            if (entityTypeRequest.getEntityType() == null) {
+                throw new MissingParameterException("Entity type not found", null);
+            }
+            if (entityTypeRequest.getEntityType().getId() == null || entityTypeRequest.
+                    getEntityType().getId().equals("")) {
+                throw new MissingParameterException("Entity type id not found", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+
+    private boolean validateTenantIdOnly(Object obj, String methodName) {
+        if (obj instanceof SearchRequest) {
+            SearchRequest entityTypeRequest = (SearchRequest) obj;
+            if (entityTypeRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateCreatePermissionTypeRequest(Object obj, String methodName) {
+        if (obj instanceof PermissionTypeRequest) {
+            PermissionTypeRequest permissionTypeRequest = (PermissionTypeRequest) obj;
+            if (permissionTypeRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+            if (permissionTypeRequest.getPermissionType() == null) {
+                throw new MissingParameterException("Permission type not found", null);
+            }
+            if (permissionTypeRequest.getPermissionType().getId() == null || permissionTypeRequest.
+                    getPermissionType().getId().equals("")) {
+                throw new MissingParameterException("Permission type id not found", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateEntityRequest(Object obj, String methodName) {
+
+        if (obj instanceof EntityRequest) {
+            EntityRequest entityRequest = (EntityRequest) obj;
+            if (entityRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+
+            if (entityRequest.getEntity() == null) {
+                throw new MissingParameterException("Entity not found ", null);
+            }
+
+            if (entityRequest.getEntity().getId() == null || entityRequest.getEntity().getId().equals("")) {
+                throw new MissingParameterException("Entity Id  not found", null);
+            }
+            if (entityRequest.getEntity().getType() == null || entityRequest.getEntity().getType().equals("")) {
+                throw new MissingParameterException("Entity type  not found", null);
+            }
+
+            if (entityRequest.getEntity().getName() == null || entityRequest.getEntity().getName().equals("")) {
+                throw new MissingParameterException("Entity name  not found", null);
+            }
+
+            if (entityRequest.getEntity().getOwnerId() == null || entityRequest.getEntity().getOwnerId().equals("")) {
+                throw new MissingParameterException("Owner Id  not found", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+
+    }
+
+    private boolean validateEntityIdentifierRequest(Object object, String methodName) {
+
+        if (object instanceof EntityRequest) {
+            EntityRequest entityRequest = (EntityRequest) object;
+            if (entityRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+
+            if (entityRequest.getEntity() == null) {
+                throw new MissingParameterException("Entity not found ", null);
+            }
+
+            if (entityRequest.getEntity().getId() == null || entityRequest.getEntity().getId().equals("")) {
+                throw new MissingParameterException("Entity Id  not found", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+
+    }
+
+    private boolean validateSearchEntityRequest(Object object, String methodName) {
+
+        if (object instanceof SearchRequest) {
+            SearchRequest entityRequest = (SearchRequest) object;
+            if (entityRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+
+            if (entityRequest.getSearchCriteriaList() == null) {
+                throw new MissingParameterException("Search Criteria  not found ", null);
+            }
+
+            if (entityRequest.getSearchCriteriaList().isEmpty()) {
+                throw new MissingParameterException("Search Criteria  not found ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+
+    private boolean validateGetSharingRequest(Object object, String methodName) {
+        if (object instanceof SharingRequest) {
+            SharingRequest entityRequest = (SharingRequest) object;
+            if (entityRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+
+            if (entityRequest.getEntity() == null) {
+                throw new MissingParameterException("Entity  is not found ", null);
+            }
+
+            if (entityRequest.getEntity().getId() == null || entityRequest.getEntity().getId().equals("")) {
+                throw new MissingParameterException("Entity id is  not found ", null);
+            }
+
+            if (entityRequest.getPermissionType() == null) {
+                throw new MissingParameterException("Permission Type is  not found ", null);
+            }
+
+            if (entityRequest.getPermissionType().getId() == null || entityRequest.getPermissionType().getId().equals("")) {
+                throw new MissingParameterException("Permission Type Id is  not found ", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateSharingRequest(Object object, String methodName) {
+        if (object instanceof SharingRequest) {
+            SharingRequest entityRequest = (SharingRequest) object;
+            if (entityRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+
+            if (entityRequest.getEntity() == null) {
+                throw new MissingParameterException("Entity  is not found ", null);
+            }
+
+            if (entityRequest.getEntity().getId() == null || entityRequest.getEntity().getId().equals("")) {
+                throw new MissingParameterException("Entity id is  not found ", null);
+            }
+
+            if (entityRequest.getPermissionType() == null) {
+                throw new MissingParameterException("Permission Type is  not found ", null);
+            }
+
+            if (entityRequest.getPermissionType().getId() == null || entityRequest.getPermissionType().getId().equals("")) {
+                throw new MissingParameterException("Permission Type Id is  not found ", null);
+            }
+
+            if (entityRequest.getOwnerIdList() == null || entityRequest.getOwnerIdList().isEmpty()) {
+                throw new MissingParameterException("Owner  Id list   not found ", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+    private boolean validateCheckAccessRequest(Object object, String methodName) {
+        if (object instanceof SharingRequest) {
+            SharingRequest entityRequest = (SharingRequest) object;
+            if (entityRequest.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id not found ", null);
+            }
+
+            if (entityRequest.getEntity() == null) {
+                throw new MissingParameterException("Entity  is not found ", null);
+            }
+
+            if (entityRequest.getEntity().getId() == null || entityRequest.getEntity().getId().equals("")) {
+                throw new MissingParameterException("Entity id is  not found ", null);
+            }
+
+            if (entityRequest.getPermissionType() == null) {
+                throw new MissingParameterException("Permission Type is  not found ", null);
+            }
+
+            if (entityRequest.getPermissionType().getId() == null || entityRequest.getPermissionType().getId().equals("")) {
+                throw new MissingParameterException("Permission Type Id is  not found ", null);
+            }
+
+            if (entityRequest.getOwnerIdList() == null || entityRequest.getOwnerIdList().isEmpty()) {
+                throw new MissingParameterException("Owner  Id list   not found ", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + methodName);
+        }
+        return true;
+    }
+
+
+}
diff --git a/custos-core-services/sharing-core-service/src/main/proto/SharingService.proto b/custos-core-services/sharing-core-service/src/main/proto/SharingService.proto
new file mode 100644
index 0000000..fff95b9
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/proto/SharingService.proto
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.sharing.service;
+
+
+enum SearchCondition {
+    EQUAL = 0;
+    LIKE = 1;
+    GTE = 2;
+    LTE = 3;
+    NOT = 4;
+}
+
+enum EntitySearchField {
+    NAME = 0;
+    DESCRIPTION = 1;
+    ID = 2;
+    FULL_TEXT = 3;
+    OWNER_ID = 4;
+    CREATED_AT = 5;
+    LAST_MODIFIED_AT = 6;
+    ENTITY_TYPE_ID = 7;
+    PARENT_ID = 8;
+    SHARED_COUNT = 9;
+    PERMISSION_TYPE_ID = 10;
+}
+
+
+message EntityType {
+    string id = 1;
+    string name = 2;
+    string description = 3;
+    int64 created_at = 4;
+    int64 updated_at = 5;
+}
+
+message PermissionType {
+    string id = 1;
+    string name = 2;
+    string description = 3;
+    int64 created_at = 4;
+    int64 updated_at = 5;
+}
+
+message Entity {
+    string id = 1;
+    string type = 2;
+    string owner_id = 3;
+    string parent_id = 4;
+    string name = 5;
+    string description = 6;
+    bytes binary_data = 7;
+    string full_text = 8;
+    int64 original_creation_time = 9;
+    int64 created_at = 10;
+    int64 updated_at = 11;
+    int32 shared_count = 12;
+}
+
+message EntityRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    Entity entity = 3;
+    string client_sec = 4;
+}
+
+message EntityTypeRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    EntityType entity_type = 3;
+    string client_sec = 4;
+}
+
+
+message PermissionTypeRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    PermissionType permission_type = 3;
+    string client_sec = 4;
+}
+
+
+message SearchCriteria {
+    EntitySearchField search_field = 1;
+    string value = 2;
+    SearchCondition condition = 3;
+}
+
+message SearchRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    string owner_id = 3;
+    int32 offset = 4;
+    int32 limit = 5;
+    repeated SearchCriteria search_criteria = 6;
+    string client_sec = 7;
+    repeated string associating_ids = 8;
+}
+
+message PermissionRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    Entity entity = 3;
+    PermissionType permission_type = 4;
+    string client_sec = 5;
+}
+
+message SharingRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    Entity entity = 3;
+    PermissionType permission_type = 4;
+    repeated string owner_id = 5;
+    bool cascade = 6;
+    string client_sec = 7;
+}
+
+message SharesFilteringRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    repeated string owner_id = 5;
+    bool cascade = 6;
+    string client_sec = 7;
+}
+
+message Status {
+    bool status = 1;
+}
+
+message EntityTypes {
+    repeated EntityType types = 1;
+}
+
+message PermissionTypes {
+    repeated PermissionType types = 1;
+}
+
+message Entities {
+    repeated Entity entity_array = 1;
+}
+
+message SharedOwners {
+    repeated string owner_ids = 1;
+}
+
+service SharingService {
+
+
+    rpc createEntityType (EntityTypeRequest) returns (Status);
+    rpc updateEntityType (EntityTypeRequest) returns (Status);
+    rpc deleteEntityType (EntityTypeRequest) returns (Status);
+    rpc getEntityType (EntityTypeRequest) returns (EntityType);
+    rpc getEntityTypes (SearchRequest) returns (EntityTypes);
+
+    rpc createPermissionType (PermissionTypeRequest) returns (Status);
+    rpc updatePermissionType (PermissionTypeRequest) returns (Status);
+    rpc deletePermissionType (PermissionTypeRequest) returns (Status);
+    rpc getPermissionType (PermissionTypeRequest) returns (PermissionType);
+    rpc getPermissionTypes (SearchRequest) returns (PermissionTypes);
+
+    rpc createEntity (EntityRequest) returns (Status);
+    rpc updateEntity (EntityRequest) returns (Status);
+    rpc isEntityExists (EntityRequest) returns (Status);
+    rpc getEntity (EntityRequest) returns (Entity);
+    rpc deleteEntity (EntityRequest) returns (Status);
+    rpc searchEntities (SearchRequest) returns (Entities);
+
+
+    rpc getListOfSharedUsers (SharingRequest) returns (SharedOwners);
+    rpc getListOfDirectlySharedUsers (SharingRequest) returns (SharedOwners);
+    rpc getListOfSharedGroups (SharingRequest) returns (SharedOwners);
+    rpc getListOfDirectlySharedGroups (SharingRequest) returns (SharedOwners);
+
+    rpc shareEntityWithUsers (SharingRequest) returns (Status);
+    rpc shareEntityWithGroups (SharingRequest) returns (Status);
+    rpc revokeEntitySharingFromUsers (SharingRequest) returns (Status);
+    rpc revokeEntitySharingFromGroups (SharingRequest) returns (Status);
+    rpc userHasAccess (SharingRequest) returns (Status);
+
+
+
+
+}
\ No newline at end of file
diff --git a/custos-core-services/sharing-core-service/src/main/resources/application.properties b/custos-core-services/sharing-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..bc2eb60
--- /dev/null
+++ b/custos-core-services/sharing-core-service/src/main/resources/application.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=sharingCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_sharing?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
+
diff --git a/custos-core-services/tenant-profile-core-service/Dockerfile b/custos-core-services/tenant-profile-core-service/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/tenant-profile-core-service/pom.xml b/custos-core-services/tenant-profile-core-service/pom.xml
new file mode 100644
index 0000000..31efefc
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/pom.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>tenant-profile-core-service</artifactId>
+
+  <dependencies>
+
+      <dependency>
+          <groupId>org.springframework.boot</groupId>
+          <artifactId>spring-boot-starter-web</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.springframework.boot</groupId>
+          <artifactId>spring-boot-starter-actuator</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>custos-core-services-commons</artifactId>
+          <version>${project.version}</version>
+      </dependency>
+
+
+
+      <dependency>
+          <groupId>io.github.lognet</groupId>
+          <artifactId>grpc-spring-boot-starter</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>io.grpc</groupId>
+          <artifactId>grpc-stub</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>io.grpc</groupId>
+          <artifactId>grpc-protobuf</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>io.grpc</groupId>
+          <artifactId>grpc-netty</artifactId>
+      </dependency>
+
+
+      <dependency>
+          <groupId>org.springframework.cloud</groupId>
+          <artifactId>spring-cloud-starter-sleuth</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.springframework.cloud</groupId>
+          <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>io.zipkin.brave</groupId>
+          <artifactId>brave-instrumentation-grpc</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>io.micrometer</groupId>
+          <artifactId>micrometer-registry-prometheus</artifactId>
+      </dependency>
+
+
+      <dependency>
+          <groupId>org.springframework.boot</groupId>
+          <artifactId>spring-boot-starter-data-jpa</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>mysql</groupId>
+          <artifactId>mysql-connector-java</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>javax.persistence</groupId>
+          <artifactId>persistence-api</artifactId>
+      </dependency>
+
+  </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+               <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/.helmignore b/custos-core-services/tenant-profile-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/Chart.yaml b/custos-core-services/tenant-profile-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..94d542e
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of custos core profile service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..31e54a6
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,64 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/templates/service.yaml b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/tenant-profile-core-service/src/main/helm/values.yaml b/custos-core-services/tenant-profile-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..fa8b2ef
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/helm/values.yaml
@@ -0,0 +1,79 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/TenantProfileServiceInitializer.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/TenantProfileServiceInitializer.java
new file mode 100644
index 0000000..349861b
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/TenantProfileServiceInitializer.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.apache.custos.tenant.profile.validator.InputValidator;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+
+@SpringBootApplication
+@EnableJpaAuditing
+public class TenantProfileServiceInitializer {
+
+    public static void main(String[] args) {
+        SpringApplication.run(TenantProfileServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator){
+        return new ServiceInterceptor(validator);
+    }
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/exceptions/MissingParameterException.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/exceptions/MissingParameterException.java
new file mode 100644
index 0000000..5f1334d
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/exceptions/MissingParameterException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.exceptions;
+
+/**
+ * Missing Parameter
+ */
+public class MissingParameterException extends RuntimeException {
+
+   public MissingParameterException(String msg, Throwable e) {
+      super(msg,e);
+   }
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/exceptions/NotUpdatableException.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/exceptions/NotUpdatableException.java
new file mode 100644
index 0000000..2a72599
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/exceptions/NotUpdatableException.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.exceptions;
+
+/**
+ * Throws when tenant is not updatable
+ */
+public class NotUpdatableException extends RuntimeException {
+    public NotUpdatableException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/exceptions/TenantNotFoundException.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/exceptions/TenantNotFoundException.java
new file mode 100644
index 0000000..4b245d1
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/exceptions/TenantNotFoundException.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.exceptions;
+
+public class TenantNotFoundException extends RuntimeException {
+    public TenantNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/mapper/AttributeUpdateMetadataMapper.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/mapper/AttributeUpdateMetadataMapper.java
new file mode 100644
index 0000000..88a1d10
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/mapper/AttributeUpdateMetadataMapper.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.mapper;
+
+import org.apache.custos.tenant.profile.persistance.model.AttributeUpdateMetadata;
+import org.apache.custos.tenant.profile.persistance.model.Contact;
+import org.apache.custos.tenant.profile.persistance.model.RedirectURI;
+import org.apache.custos.tenant.profile.persistance.model.Tenant;
+import org.apache.custos.tenant.profile.service.TenantAttributeUpdateMetadata;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class maps attributes between grpc TenantAttributeUpdateMetadata to DB AttributeUpdateMetadata table
+ */
+public class AttributeUpdateMetadataMapper {
+
+
+    /**
+     * This creates Attribute update entity List from comparing oldTenant and newTenant
+     *
+     * @param oldTenant
+     * @param newTenant
+     * @param updatedBy
+     * @return
+     */
+    public static Set<AttributeUpdateMetadata> createAttributeUpdateMetadataEntity(Tenant oldTenant, Tenant newTenant, String updatedBy) {
+
+        Set<AttributeUpdateMetadata> metadataSet = new HashSet<>();
+        if (!oldTenant.getName().equals(newTenant.getName())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("name");
+            attributeUpdateMetadata.setUpdatedFieldValue(newTenant.getName());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldTenant.getAdminEmail().equals(newTenant.getAdminEmail())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("adminEmail");
+            attributeUpdateMetadata.setUpdatedFieldValue(newTenant.getAdminEmail());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldTenant.getAdminFirstName().equals(newTenant.getAdminFirstName())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("adminFirstName");
+            attributeUpdateMetadata.setUpdatedFieldValue(newTenant.getAdminFirstName());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldTenant.getAdminLastName().equals(newTenant.getAdminLastName())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("adminLastName");
+            attributeUpdateMetadata.setUpdatedFieldValue(newTenant.getAdminLastName());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldTenant.getDomain().equals(newTenant.getDomain())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("domain");
+            attributeUpdateMetadata.setUpdatedFieldValue(newTenant.getDomain());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldTenant.getLogoURI().equals(newTenant.getLogoURI())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("logoURI");
+            attributeUpdateMetadata.setUpdatedFieldValue(newTenant.getLogoURI());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldTenant.getRequesterEmail().equals(newTenant.getRequesterEmail())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("requesterEmail");
+            attributeUpdateMetadata.setUpdatedFieldValue(newTenant.getRequesterEmail());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+
+        if (!oldTenant.getScope().equals(newTenant.getScope())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("scope");
+            attributeUpdateMetadata.setUpdatedFieldValue(newTenant.getScope());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+         Set diff =   difference(oldTenant.getRedirectURIS(), newTenant.getRedirectURIS());
+
+        if (!diff.isEmpty()) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("redirectURIS");
+            attributeUpdateMetadata.setUpdatedFieldValue(setToString(diff));
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        Set conDiff = difference(oldTenant.getContacts(), newTenant.getContacts());
+        if (!conDiff.isEmpty()) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setTenant(newTenant);
+            attributeUpdateMetadata.setUpdatedFieldKey("contacts");
+            attributeUpdateMetadata.setUpdatedFieldValue(setToString(conDiff));
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            attributeUpdateMetadata.setTenant(newTenant);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+        return metadataSet;
+    }
+
+
+    /**
+     * create attribute update metadata from db entity
+     * @param metadata
+     * @return
+     */
+    public static TenantAttributeUpdateMetadata createAttributeUpdateMetadataFromEntity (AttributeUpdateMetadata metadata) {
+
+        return TenantAttributeUpdateMetadata.newBuilder()
+                 .setUpdatedAt(metadata.getUpdatedAt().toString())
+                .setUpdatedBy(metadata.getUpdatedBy())
+                .setUpdatedAttributeValue(metadata.getUpdatedFieldValue())
+                .setUpdatedAttribute(metadata.getUpdatedFieldKey())
+                .build();
+    }
+
+
+
+    private static <T> Set<T> difference(final Set<T> setOne, final Set<T> setTwo) {
+        Set<T> result = new HashSet<T>(setOne);
+        result.removeIf(setTwo::contains);
+        return result;
+    }
+
+    private static String setToString(Set<Object> result){
+        StringBuffer buffer = new StringBuffer();
+        if (!result.isEmpty()) {
+            for (Object t : result){
+                if (t instanceof RedirectURI) {
+                    buffer.append(((RedirectURI)t).getRedirectURI());
+                } else {
+                    buffer.append(((Contact)t).getContactInfo());
+                }
+                buffer.append(",");
+            }
+        }
+        return buffer.toString();
+    }
+
+
+
+
+
+
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/mapper/StatusUpdateMetadataMapper.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/mapper/StatusUpdateMetadataMapper.java
new file mode 100644
index 0000000..29440eb
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/mapper/StatusUpdateMetadataMapper.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.mapper;
+
+import org.apache.custos.tenant.profile.persistance.model.StatusUpdateMetadata;
+import org.apache.custos.tenant.profile.persistance.model.Tenant;
+import org.apache.custos.tenant.profile.service.TenantStatus;
+import org.apache.custos.tenant.profile.service.TenantStatusUpdateMetadata;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class maps attributes between grpc TenantStatusUpdateMetadata to DB StatusUpdateMetadata table
+ */
+public class StatusUpdateMetadataMapper {
+
+
+    /**
+     * Creates Status update entity for save in DB
+     *
+     * @param {@link    org.apache.custos.tenant.profile.service.Tenant} tenant
+     * @param updatedBy
+     * @return
+     */
+    public static Set<StatusUpdateMetadata>  createStatusUpdateMetadataEntity(Tenant tenant, String updatedBy) {
+
+        Set<StatusUpdateMetadata> metaDataSet = new HashSet<>();
+
+        StatusUpdateMetadata metadata = new StatusUpdateMetadata();
+        metadata.setTenant(tenant);
+        metadata.setUpdatedBy(updatedBy);
+        metadata.setUpdatedStatus(tenant.getStatus());
+
+        metaDataSet.add(metadata);
+        return metaDataSet;
+
+    }
+
+    /**
+     * convert TenantStatusUpdateMetadataEntity to gRPC TenantStatusUpdateMetadata
+     *
+     * @param metadata
+     * @return TenantStatusUpdateMetadata
+     */
+    public static TenantStatusUpdateMetadata createTenantStatusMetadataFrom(StatusUpdateMetadata metadata) {
+        return TenantStatusUpdateMetadata.newBuilder()
+                .setUpdatedAt(metadata.getUpdatedAt().toString())
+                .setUpdatedBy(metadata.getUpdatedBy())
+                .setUpdatedStatus(TenantStatus.valueOf(metadata.getUpdatedStatus())).build();
+
+    }
+
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/mapper/TenantMapper.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/mapper/TenantMapper.java
new file mode 100644
index 0000000..5ab26af
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/mapper/TenantMapper.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.mapper;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.custos.tenant.profile.persistance.model.Contact;
+import org.apache.custos.tenant.profile.persistance.model.RedirectURI;
+import org.apache.custos.tenant.profile.persistance.model.Tenant;
+import org.apache.custos.tenant.profile.service.TenantStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+
+/**
+ * This class maps attributes between grpc Tenant to DB Tenant table
+ */
+public class TenantMapper {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(TenantMapper.class);
+
+    /**
+     * Maps gRPC Tenant Model to DB Layer Tenant Entity
+     *
+     * @param {@link org.apache.custos.tenant.profile.service.Tenant} tenant
+     * @return Tenant
+     */
+    public static Tenant createTenantEntityFromTenant(org.apache.custos.tenant.profile.service.Tenant tenant) {
+        Tenant tenantEntity = new Tenant();
+        tenantEntity.setId(tenant.getTenantId());
+        tenantEntity.setName(tenant.getClientName());
+        tenantEntity.setStatus(tenant.getTenantStatus().name());
+        tenantEntity.setAdminFirstName(tenant.getAdminFirstName());
+        tenantEntity.setAdminLastName(tenant.getAdminLastName());
+        tenantEntity.setAdminEmail(tenant.getAdminEmail());
+        tenantEntity.setRequesterEmail(tenant.getRequesterEmail());
+        tenantEntity.setLogoURI(tenant.getClientUri());
+        tenantEntity.setScope(tenant.getScope());
+        tenantEntity.setDomain(tenant.getDomain());
+        tenantEntity.setAdminUsername(tenant.getAdminUsername());
+        tenantEntity.setComment(tenant.getComment());
+        tenantEntity.setUri(tenant.getClientUri());
+        tenantEntity.setParentId(tenant.getParentTenantId());
+        tenantEntity.setApplicationType(tenant.getApplicationType());
+        tenantEntity.setJwks(tenant.getJwksCount() > 0 ? getJWKSAsString(tenant.getJwksMap()) : null);
+        tenantEntity.setJwksUri(tenant.getJwksUri());
+        tenantEntity.setExample_extension_parameter(tenant.getExampleExtensionParameter());
+        tenantEntity.setTosUri(tenant.getTosUri());
+        tenantEntity.setPolicyUri(tenant.getPolicyUri());
+        tenantEntity.setSoftwareId(tenant.getSoftwareId());
+        tenantEntity.setSoftwareVersion(tenant.getSoftwareVersion());
+        tenantEntity.setRefreshTokenLifetime(tenant.getRefeshTokenLifetime());
+
+
+        Set<Contact> contactSet = new HashSet<Contact>();
+
+        for (int i = 0; i < tenant.getContactsCount(); i++) {
+
+            String contact = tenant.getContacts(i);
+            Contact contactEntity = new Contact();
+            contactEntity.setTenant(tenantEntity);
+            contactEntity.setContactInfo(contact);
+            contactSet.add(contactEntity);
+        }
+
+        tenantEntity.setContacts(contactSet);
+
+        Set<RedirectURI> redirectURIS = new HashSet<RedirectURI>();
+        for (int i = 0; i < tenant.getRedirectUrisCount(); i++) {
+
+            String uri = tenant.getRedirectUris(i);
+            RedirectURI redirectURIEntity = new RedirectURI();
+            redirectURIEntity.setTenant(tenantEntity);
+            redirectURIEntity.setRedirectURI(uri);
+            redirectURIS.add(redirectURIEntity);
+        }
+
+        tenantEntity.setRedirectURIS(redirectURIS);
+
+        return tenantEntity;
+
+    }
+
+
+    /**
+     * Transform TenantEntity to Tenant
+     *
+     * @param tenantEntity
+     * @return tenant
+     */
+    public static org.apache.custos.tenant.profile.service.Tenant createTenantFromTenantEntity(Tenant tenantEntity) {
+
+        Set<Contact> contacts = tenantEntity.getContacts();
+        List<String> contactList = new ArrayList<>();
+        if (contacts != null && !contacts.isEmpty()) {
+            for (Contact contact : contacts) {
+                contactList.add(contact.getContactInfo());
+            }
+        }
+
+
+        Set<RedirectURI> redirectURIS = tenantEntity.getRedirectURIS();
+        List<String> uriList = new ArrayList<>();
+        if (redirectURIS != null && !redirectURIS.isEmpty()) {
+            for (RedirectURI redirectURI : redirectURIS) {
+                uriList.add(redirectURI.getRedirectURI());
+            }
+        }
+
+
+        return org.apache.custos.tenant.profile.service.Tenant.newBuilder()
+                .setAdminEmail(tenantEntity.getAdminEmail())
+                .setAdminFirstName(tenantEntity.getAdminFirstName())
+                .setAdminLastName(tenantEntity.getAdminLastName())
+                .setDomain(tenantEntity.getDomain())
+                .setClientUri(tenantEntity.getLogoURI())
+                .setRequesterEmail(tenantEntity.getRequesterEmail())
+                .setScope(tenantEntity.getScope())
+                .addAllContacts(contactList)
+                .addAllRedirectUris(uriList)
+                .setClientName(tenantEntity.getName())
+                .setTenantId(tenantEntity.getId())
+                .setTenantStatus(TenantStatus.valueOf(tenantEntity.getStatus()))
+                .setAdminUsername(tenantEntity.getAdminUsername())
+                .setComment(tenantEntity.getComment())
+                .setLogoUri(tenantEntity.getLogoURI())
+                .setApplicationType(tenantEntity.getApplicationType())
+                .setJwksUri(tenantEntity.getJwksUri())
+                .setExampleExtensionParameter(tenantEntity.getExample_extension_parameter())
+                .setTosUri(tenantEntity.getTosUri())
+                .setPolicyUri(tenantEntity.getPolicyUri())
+                .setSoftwareId(tenantEntity.getSoftwareId())
+                .setSoftwareVersion(tenantEntity.getSoftwareVersion())
+                .setRefeshTokenLifetime(tenantEntity.getRefreshTokenLifetime())
+                .setParentTenantId(tenantEntity.getParentId())
+                .build();
+
+
+    }
+
+
+    public static String getTenantInfoAsString(org.apache.custos.tenant.profile.service.Tenant tenant) {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("tenantName : " + tenant.getClientName());
+        buffer.append("\n");
+        buffer.append("tenantId : " + tenant.getTenantId());
+        buffer.append("\n");
+        buffer.append("tenantAdminEmail : " + tenant.getAdminEmail());
+        buffer.append("\n");
+        buffer.append("tenantAdminFirstName : " + tenant.getAdminFirstName());
+        buffer.append("\n");
+        buffer.append("tenantAdminLastName : " + tenant.getAdminLastName());
+        buffer.append("domain : " + tenant.getDomain());
+        buffer.append("\n");
+        buffer.append("logoURI : " + tenant.getClientUri());
+        buffer.append("\n");
+        buffer.append("\n");
+        buffer.append("requesterEmail : " + tenant.getRequesterEmail());
+        buffer.append("\n");
+        buffer.append("tenantScope : " + tenant.getScope());
+        buffer.append("\n");
+        buffer.append("contacts  : " + tenant.getContactsList().toString());
+        buffer.append("\n");
+        buffer.append("redirectURIs : " + tenant.getRedirectUrisList().toString());
+        buffer.append("\n");
+
+        return buffer.toString();
+
+    }
+
+
+    private static String getJWKSAsString(Map<String, String> jwksMap) {
+        ObjectMapper objectMapper = new ObjectMapper();
+
+        try {
+            return objectMapper.writeValueAsString(jwksMap);
+        } catch (JsonProcessingException e) {
+            LOGGER.error("Error occurred while printing json ", e);
+            return null;
+        }
+    }
+
+
+}
+
+
+
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/AttributeUpdateMetadata.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/AttributeUpdateMetadata.java
new file mode 100644
index 0000000..237e538
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/AttributeUpdateMetadata.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Keeps track of attribute updated metadata
+ */
+@Entity
+@Table(name = "attribute_update_metadata")
+@EntityListeners(AuditingEntityListener.class)
+public class AttributeUpdateMetadata {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String updatedFieldKey;
+
+    @Lob
+    @Column(nullable = false)
+    private String updatedFieldValue;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date updatedAt;
+
+    @Column(nullable = false)
+    private String updatedBy;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "tenant_id")
+    private Tenant tenant;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUpdatedFieldKey() {
+        return updatedFieldKey;
+    }
+
+    public void setUpdatedFieldKey(String updatedFieldKey) {
+        this.updatedFieldKey = updatedFieldKey;
+    }
+
+    public String getUpdatedFieldValue() {
+        return updatedFieldValue;
+    }
+
+    public void setUpdatedFieldValue(String updatedFieldValue) {
+        this.updatedFieldValue = updatedFieldValue;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public String getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(String updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public Tenant getTenant() {
+        return tenant;
+    }
+
+    public void setTenant(Tenant tenant) {
+        this.tenant = tenant;
+    }
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/Contact.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/Contact.java
new file mode 100644
index 0000000..3651798
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/Contact.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.model;
+
+import javax.persistence.*;
+
+/**
+ * This class represents the contact information of Tenant
+ */
+@Entity
+@Table(name = "contact")
+public class Contact {
+
+    @Id
+    @GeneratedValue (strategy = GenerationType.AUTO)
+    private Long id ;
+
+    private String contactInfo;
+
+    @ManyToOne
+    @JoinColumn(name = "tenant_id")
+    private Tenant tenant;
+
+
+    public String getContactInfo() {
+        return contactInfo;
+    }
+
+    public void setContactInfo(String contactInfo) {
+        this.contactInfo = contactInfo;
+    }
+
+    public Tenant getTenant() {
+        return tenant;
+    }
+
+    public void setTenant(Tenant tenant) {
+        this.tenant = tenant;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return this.contactInfo.equals(((Contact)obj).getContactInfo());
+    }
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/RedirectURI.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/RedirectURI.java
new file mode 100644
index 0000000..ba7b762
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/RedirectURI.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.model;
+
+import javax.persistence.*;
+
+/**
+ * This represents the redirectURIs of a tenants
+ */
+@Entity
+@Table(name = "redirect_uri")
+public class RedirectURI {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id ;
+
+    @Column(name = "redirect_uri")
+    private String redirectURI;
+
+    @ManyToOne
+    @JoinColumn(name = "tenant_id")
+    private Tenant tenant;
+
+
+    public String getRedirectURI() {
+        return redirectURI;
+    }
+
+    public void setRedirectURI(String redirectURI) {
+        this.redirectURI = redirectURI;
+    }
+
+    public Tenant getTenant() {
+        return tenant;
+    }
+
+    public void setTenant(Tenant tenant) {
+        this.tenant = tenant;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+
+    @Override
+    public boolean equals(Object obj) {
+        return this.redirectURI.equals(((RedirectURI)obj).getRedirectURI());
+    }
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/StatusUpdateMetadata.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/StatusUpdateMetadata.java
new file mode 100644
index 0000000..2c8d729
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/StatusUpdateMetadata.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Keeps the track of status updated metadata
+ */
+@Entity
+@Table(name = "status_update_metadata")
+@EntityListeners(AuditingEntityListener.class)
+public class StatusUpdateMetadata {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String updatedStatus;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date updatedAt;
+
+    @Column(nullable = false)
+    private String updatedBy;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "tenant_id")
+    private Tenant tenant;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUpdatedStatus() {
+        return updatedStatus;
+    }
+
+    public void setUpdatedStatus(String updatedStatus) {
+        this.updatedStatus = updatedStatus;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+
+
+    public String getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(String updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public Tenant getTenant() {
+        return tenant;
+    }
+
+    public void setTenant(Tenant tenant) {
+        this.tenant = tenant;
+    }
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/Tenant.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/Tenant.java
new file mode 100644
index 0000000..60244e7
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/model/Tenant.java
@@ -0,0 +1,344 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.model;
+
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * Represents tenant table at DB
+ */
+@Entity
+@Table(name = "tenant")
+@EntityListeners(AuditingEntityListener.class)
+public class Tenant {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tenant_id_generator")
+    @SequenceGenerator(name = "tenant_id_generator", sequenceName = "tenant_sequence", initialValue = 10000000, allocationSize = 100)
+    private Long id;
+
+    @Column(nullable = false)
+    private String name;
+
+    @Column(nullable = false)
+    private String domain;
+
+    @Column(nullable = false)
+    private String requesterEmail;
+
+    @Column(nullable = false)
+    private String status;
+
+    @Column(nullable = false)
+    private String adminFirstName;
+
+    @Column(nullable = false)
+    private String adminLastName;
+
+    @Column(nullable = false)
+    private String adminEmail;
+
+    @Column(nullable = false)
+    private String adminUsername;
+
+
+    @Column(name = "tenant_uri")
+    private String logoURI;
+
+    @Column(nullable = false)
+    private String scope;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    private String uri;
+
+    private String comment;
+
+    private long parentId;
+
+    @Column(nullable = false)
+    private String applicationType;
+
+    private String jwksUri;
+
+    private String example_extension_parameter;
+
+    private String tosUri;
+
+    private String policyUri;
+
+    private String jwks;
+
+    private String softwareId;
+
+    private String softwareVersion;
+
+    private long refreshTokenLifetime = 0;
+
+
+    @OneToMany(mappedBy = "tenant", cascade = CascadeType.ALL,orphanRemoval = true, fetch = FetchType.EAGER)
+    private Set<Contact> contacts;
+
+    @OneToMany(mappedBy = "tenant", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
+    private Set<RedirectURI> redirectURIS;
+
+    @OneToMany(mappedBy = "tenant", cascade = CascadeType.ALL)
+    private Set<AttributeUpdateMetadata> attributeUpdateMetadata;
+
+    @OneToMany(mappedBy = "tenant", cascade = CascadeType.ALL)
+    private Set<StatusUpdateMetadata> statusUpdateMetadata;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public String getRequesterEmail() {
+        return requesterEmail;
+    }
+
+    public void setRequesterEmail(String requesterEmail) {
+        this.requesterEmail = requesterEmail;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getAdminFirstName() {
+        return adminFirstName;
+    }
+
+    public void setAdminFirstName(String adminFirstName) {
+        this.adminFirstName = adminFirstName;
+    }
+
+    public String getAdminLastName() {
+        return adminLastName;
+    }
+
+    public void setAdminLastName(String adminLastName) {
+        this.adminLastName = adminLastName;
+    }
+
+    public String getAdminEmail() {
+        return adminEmail;
+    }
+
+    public void setAdminEmail(String adminEmail) {
+        this.adminEmail = adminEmail;
+    }
+
+
+    public String getLogoURI() {
+        return logoURI;
+    }
+
+    public void setLogoURI(String logoURI) {
+        this.logoURI = logoURI;
+    }
+
+    public String getScope() {
+        return scope;
+    }
+
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+
+    public Set<Contact> getContacts() {
+        return contacts;
+    }
+
+    public void setContacts(Set<Contact> contacts) {
+        this.contacts = contacts;
+    }
+
+    public Set<RedirectURI> getRedirectURIS() {
+        return redirectURIS;
+    }
+
+    public void setRedirectURIS(Set<RedirectURI> redirectURIS) {
+        this.redirectURIS = redirectURIS;
+    }
+
+    public Set<AttributeUpdateMetadata> getAttributeUpdateMetadata() {
+        return attributeUpdateMetadata;
+    }
+
+    public void setAttributeUpdateMetadata(Set<AttributeUpdateMetadata> attributeUpdateMetadata) {
+        this.attributeUpdateMetadata = attributeUpdateMetadata;
+    }
+
+    public Set<StatusUpdateMetadata> getStatusUpdateMetadata() {
+        return statusUpdateMetadata;
+    }
+
+    public void setStatusUpdateMetadata(Set<StatusUpdateMetadata> statusUpdateMetadata) {
+        this.statusUpdateMetadata = statusUpdateMetadata;
+    }
+
+    public String getAdminUsername() {
+        return adminUsername;
+    }
+
+    public void setAdminUsername(String adminUsername) {
+        this.adminUsername = adminUsername;
+    }
+
+
+    public String getUri() {
+        return uri;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(long parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getApplicationType() {
+        return applicationType;
+    }
+
+    public void setApplicationType(String applicationType) {
+        this.applicationType = applicationType;
+    }
+
+
+    public String getJwksUri() {
+        return jwksUri;
+    }
+
+    public void setJwksUri(String jwksUri) {
+        this.jwksUri = jwksUri;
+    }
+
+    public String getExample_extension_parameter() {
+        return example_extension_parameter;
+    }
+
+    public void setExample_extension_parameter(String example_extension_parameter) {
+        this.example_extension_parameter = example_extension_parameter;
+    }
+
+    public String getTosUri() {
+        return tosUri;
+    }
+
+    public void setTosUri(String tosUri) {
+        this.tosUri = tosUri;
+    }
+
+    public String getPolicyUri() {
+        return policyUri;
+    }
+
+    public void setPolicyUri(String policyUri) {
+        this.policyUri = policyUri;
+    }
+
+    public String getJwks() {
+        return jwks;
+    }
+
+    public void setJwks(String jwks) {
+        this.jwks = jwks;
+    }
+
+    public String getSoftwareId() {
+        return softwareId;
+    }
+
+    public void setSoftwareId(String softwareId) {
+        this.softwareId = softwareId;
+    }
+
+    public String getSoftwareVersion() {
+        return softwareVersion;
+    }
+
+    public void setSoftwareVersion(String softwareVersion) {
+        this.softwareVersion = softwareVersion;
+    }
+
+    public long getRefreshTokenLifetime() {
+        return refreshTokenLifetime;
+    }
+
+    public void setRefreshTokenLifetime(long refreshTokenLifetime) {
+        this.refreshTokenLifetime = refreshTokenLifetime;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/AttributeUpdateMetadataRepository.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/AttributeUpdateMetadataRepository.java
new file mode 100644
index 0000000..2c4094e
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/AttributeUpdateMetadataRepository.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.respository;
+
+import org.apache.custos.tenant.profile.persistance.model.AttributeUpdateMetadata;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface AttributeUpdateMetadataRepository extends JpaRepository<AttributeUpdateMetadata, Long> {
+
+    public List<AttributeUpdateMetadata> findAllByTenantId(Long tenant);
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/ContactRepository.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/ContactRepository.java
new file mode 100644
index 0000000..fe45648
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/ContactRepository.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.respository;
+
+import org.apache.custos.tenant.profile.persistance.model.Contact;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface ContactRepository  extends JpaRepository<Contact, Long>  {
+
+    @Transactional
+    public void deleteAllByTenantId(Long tenantId);
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/RedirectURIRepository.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/RedirectURIRepository.java
new file mode 100644
index 0000000..f1e85d4
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/RedirectURIRepository.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.respository;
+
+import org.apache.custos.tenant.profile.persistance.model.Contact;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface RedirectURIRepository extends JpaRepository<Contact, Long> {
+
+    @Transactional
+    public void deleteAllByTenantId(Long tenantId);
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/StatusUpdateMetadataRepository.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/StatusUpdateMetadataRepository.java
new file mode 100644
index 0000000..d5d7874
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/StatusUpdateMetadataRepository.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.respository;
+
+import org.apache.custos.tenant.profile.persistance.model.StatusUpdateMetadata;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface StatusUpdateMetadataRepository extends JpaRepository<StatusUpdateMetadata, Long> {
+
+
+    public List<StatusUpdateMetadata> findAllByTenantId(Long tenant);
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/TenantRepository.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/TenantRepository.java
new file mode 100644
index 0000000..0f0a48b
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/persistance/respository/TenantRepository.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.persistance.respository;
+
+import org.apache.custos.tenant.profile.persistance.model.Tenant;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+public interface TenantRepository extends JpaRepository<Tenant, Long> {
+
+    public List<Tenant> findByRequesterEmail(String requesterEmail);
+
+    public List<Tenant> findByDomainAndName(String domain, String name);
+
+    @Query(value = "select * from tenant t where t.status LIKE ?1 order by t.id limit ?2 offset ?3", nativeQuery = true)
+    public List<Tenant> findByStatusWithPaginate(String status, int limit, int offset);
+
+    @Query(value = "select * from tenant order by id limit ?1  offset ?2", nativeQuery = true)
+    public List<Tenant> getAllWithPaginate(int limit, int offset);
+
+    @Query(value = "select * from tenant t where t.status LIKE ?1 and t.parent_id LIKE ?2 order by t.id limit ?3 offset ?4", nativeQuery = true)
+    public List<Tenant> findChildTenantsByStatusWithPaginate(String status, long parentId, int limit, int offset);
+
+    @Query(value = "select * from tenant t where t.parent_id LIKE ?1 order by t.id limit ?2  offset ?3", nativeQuery = true)
+    public List<Tenant> getAllChildTenantsWithPaginate(long parentId, int limit, int offset);
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/service/TenantProfileService.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/service/TenantProfileService.java
new file mode 100644
index 0000000..defb7a2
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/service/TenantProfileService.java
@@ -0,0 +1,427 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.service;
+
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.tenant.profile.mapper.AttributeUpdateMetadataMapper;
+import org.apache.custos.tenant.profile.mapper.StatusUpdateMetadataMapper;
+import org.apache.custos.tenant.profile.mapper.TenantMapper;
+import org.apache.custos.tenant.profile.persistance.model.AttributeUpdateMetadata;
+import org.apache.custos.tenant.profile.persistance.model.StatusUpdateMetadata;
+import org.apache.custos.tenant.profile.persistance.model.Tenant;
+import org.apache.custos.tenant.profile.persistance.respository.*;
+import org.apache.custos.tenant.profile.service.TenantProfileServiceGrpc.TenantProfileServiceImplBase;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * This service is responsible for custos gateway management functions
+ */
+@GRpcService
+public class TenantProfileService extends TenantProfileServiceImplBase {
+    private static final Logger LOGGER = LoggerFactory.getLogger(TenantProfileService.class);
+
+
+    @Autowired
+    private TenantRepository tenantRepository;
+
+    @Autowired
+    private StatusUpdateMetadataRepository statusUpdateMetadataRepository;
+
+    @Autowired
+    private AttributeUpdateMetadataRepository attributeUpdateMetadataRepository;
+
+    @Autowired
+    private ContactRepository contactRepository;
+
+    @Autowired
+    private RedirectURIRepository redirectURIRepository;
+
+
+    @Override
+    public void addTenant(org.apache.custos.tenant.profile.service.Tenant request,
+                          StreamObserver<org.apache.custos.tenant.profile.service.Tenant> responseObserver) {
+
+        try {
+            LOGGER.debug("Add tenant request received for tenant " + TenantMapper.getTenantInfoAsString(request));
+
+            Tenant tenant = TenantMapper.createTenantEntityFromTenant(request);
+
+            tenant.setStatus(TenantStatus.REQUESTED.name());
+
+            Set<StatusUpdateMetadata> metadataSet = StatusUpdateMetadataMapper.
+                    createStatusUpdateMetadataEntity(tenant, tenant.getRequesterEmail());
+
+            tenant.setStatusUpdateMetadata(metadataSet);
+
+
+            Tenant savedTenant = tenantRepository.save(tenant);
+
+
+            org.apache.custos.tenant.profile.service.Tenant
+                    response = request.toBuilder().setTenantId(savedTenant.getId()).build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while adding the tenant " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+
+        }
+
+
+    }
+
+    @Override
+    public void updateTenant(org.apache.custos.tenant.profile.service.Tenant tenant, StreamObserver<org.apache.custos.tenant.profile.service.Tenant> responseObserver) {
+        try {
+            LOGGER.debug("Update tenant request received for tenant " + TenantMapper.
+                    getTenantInfoAsString(tenant));
+
+
+            String updatedBy = "Tenant Admin";
+
+            Long tenantId = tenant.getTenantId();
+
+            if (!isUpdatable(tenantId, tenant.getDomain(), tenant.getClientName())) {
+                String msg = "Tenant not exist";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            Optional<Tenant> opt = tenantRepository.findById(tenantId);
+            Tenant exTenant = opt.get();
+            tenant = tenant.toBuilder().setParentTenantId(exTenant.getParentId()).build();
+            Tenant tenantEntity = TenantMapper.createTenantEntityFromTenant(tenant);
+
+            //Do not update the tenant status
+
+            if (tenantEntity.getParentId() > 0) {
+
+                tenantEntity.setStatus(exTenant.getStatus());
+            } else {
+                tenantEntity.setStatus(TenantStatus.REQUESTED.name());
+            }
+
+            tenantEntity.setCreatedAt(exTenant.getCreatedAt());
+
+
+            Set<AttributeUpdateMetadata> metadata = AttributeUpdateMetadataMapper.
+                    createAttributeUpdateMetadataEntity(exTenant, tenantEntity, updatedBy);
+
+            tenantEntity.setAttributeUpdateMetadata(metadata);
+
+            contactRepository.deleteAllByTenantId(tenantId);
+
+            redirectURIRepository.deleteAllByTenantId(tenantId);
+
+            tenantRepository.save(tenantEntity);
+
+            responseObserver.onNext(tenant);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while updating the tenant " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+
+        }
+    }
+
+    @Override
+    public void getAllTenants(GetTenantsRequest request, StreamObserver<GetAllTenantsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Get all tenants request received");
+
+            String status = null;
+
+            if (request.getStatus() != null && !request.getStatus().name().equals("")){
+                status = request.getStatus().name();
+            }
+
+            int offset = request.getOffset();
+            int limit = request.getLimit();
+            long parentId = request.getParentId();
+
+            String requesterEmail = request.getRequesterEmail();
+
+            List<Tenant> tenants = null;
+
+            if (requesterEmail != null && !requesterEmail.equals("")) {
+              tenants = tenantRepository.findByRequesterEmail(requesterEmail);
+            } else if (status == null && parentId == 0) {
+                tenants = tenantRepository.getAllWithPaginate(limit,offset);
+            } else if (status != null && parentId == 0){
+                tenants = tenantRepository.findByStatusWithPaginate(status,limit,offset);
+            } else if (status == null && parentId > 0) {
+                tenants = tenantRepository.getAllChildTenantsWithPaginate(parentId,limit,offset);
+            } else if (status != null && parentId >0 ) {
+                tenants = tenantRepository.findChildTenantsByStatusWithPaginate(status,parentId,limit,offset);
+            }
+
+
+            List<org.apache.custos.tenant.profile.service.Tenant> tenantList = new ArrayList<>();
+
+            for (Tenant tenant : tenants) {
+                org.apache.custos.tenant.profile.service.Tenant t = TenantMapper.createTenantFromTenantEntity(tenant);
+                tenantList.add(t);
+            }
+
+            GetAllTenantsResponse response = GetAllTenantsResponse.newBuilder().addAllTenant(tenantList).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while retrieving  tenants " + ex;
+            ex.printStackTrace();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAllTenantsForUser(GetAllTenantsForUserRequest request,
+                                     StreamObserver<GetAllTenantsForUserResponse> responseObserver) {
+        try {
+            LOGGER.debug("Get all tenants for user " + request.getRequesterEmail() + " received");
+
+            String username = request.getRequesterEmail();
+
+            List<Tenant> tenants = tenantRepository.findByRequesterEmail(username);
+
+            List<org.apache.custos.tenant.profile.service.Tenant> tenantList = new ArrayList<>();
+
+            for (Tenant tenant : tenants) {
+                org.apache.custos.tenant.profile.service.Tenant t = TenantMapper.createTenantFromTenantEntity(tenant);
+                tenantList.add(t);
+            }
+
+            GetAllTenantsForUserResponse response = GetAllTenantsForUserResponse.newBuilder()
+                    .addAllTenant(tenantList).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while retrieving  tenants " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getTenant(GetTenantRequest request, StreamObserver<GetTenantResponse> responseObserver) {
+        try {
+            LOGGER.debug("Get tenant with Id " + request.getTenantId() + " received");
+
+            Long id = request.getTenantId();
+
+            Optional<Tenant> tenant = tenantRepository.findById(id);
+            org.apache.custos.tenant.profile.service.Tenant t = null;
+            if (tenant.isPresent()) {
+                t = TenantMapper.createTenantFromTenantEntity(tenant.get());
+                GetTenantResponse response = GetTenantResponse.newBuilder().setTenant(t).build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            } else {
+                String msg = "Cannot find the tenant with Id " + t.getTenantId();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while retrieving  tenants " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getTenantAttributeUpdateAuditTrail(GetAuditTrailRequest request,
+                                                   StreamObserver<GetAttributeUpdateAuditTrailResponse> responseObserver) {
+        try {
+            LOGGER.debug("Get tenant attribute update audit trail for  " + request.getTenantId());
+
+            Long id = Long.valueOf(request.getTenantId());
+
+            List<AttributeUpdateMetadata> tenantList = attributeUpdateMetadataRepository.findAllByTenantId(id);
+            List<TenantAttributeUpdateMetadata> metadata = new ArrayList<>();
+
+            for (AttributeUpdateMetadata attributeUpdateMetadata : tenantList) {
+
+                TenantAttributeUpdateMetadata updatedMetadata = AttributeUpdateMetadataMapper.
+                        createAttributeUpdateMetadataFromEntity(attributeUpdateMetadata);
+                metadata.add(updatedMetadata);
+
+            }
+
+            GetAttributeUpdateAuditTrailResponse response = GetAttributeUpdateAuditTrailResponse
+                    .newBuilder()
+                    .addAllMetadata(metadata)
+                    .build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while retrieving  attribute status update metadata " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getTenantStatusUpdateAuditTrail(GetAuditTrailRequest request,
+                                                StreamObserver<GetStatusUpdateAuditTrailResponse> responseObserver) {
+        try {
+            LOGGER.debug("Get tenant attribute update audit trail for  " + request.getTenantId());
+
+            Long id = request.getTenantId();
+
+            List<StatusUpdateMetadata> tenantList = statusUpdateMetadataRepository.findAllByTenantId(id);
+            List<TenantStatusUpdateMetadata> metadata = new ArrayList<>();
+
+            for (StatusUpdateMetadata statusUpdateMetadata : tenantList) {
+
+                TenantStatusUpdateMetadata updatedMetadata = StatusUpdateMetadataMapper
+                        .createTenantStatusMetadataFrom(statusUpdateMetadata);
+                metadata.add(updatedMetadata);
+
+            }
+
+            GetStatusUpdateAuditTrailResponse response = GetStatusUpdateAuditTrailResponse
+                    .newBuilder()
+                    .addAllMetadata(metadata)
+                    .build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while retrieving  status update metadata " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void isTenantExist(IsTenantExistRequest request, StreamObserver<IsTenantExistResponse> responseObserver) {
+        try {
+            LOGGER.debug("Is tenant exist " + request.getTenantId() + " received");
+
+            Long id = Long.valueOf(request.getTenantId());
+
+            Optional<Tenant> tenant = tenantRepository.findById(id);
+
+
+            IsTenantExistResponse response = IsTenantExistResponse.newBuilder().setIsExist(tenant.isPresent()).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while retrieving  tenants " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updateTenantStatus(UpdateStatusRequest request, StreamObserver<UpdateStatusResponse> responseObserver) {
+        try {
+            LOGGER.debug("Update tenant request status received for " + request.getTenantId() + " received");
+
+            Long id = request.getTenantId();
+
+            String status = request.getStatus().name();
+
+            String updatedBy = request.getUpdatedBy();
+
+            Optional<Tenant> tenant = tenantRepository.findById(id);
+
+            if (tenant.isPresent()) {
+
+                Tenant t = tenant.get();
+
+                t.setStatus(status);
+
+                Set<StatusUpdateMetadata> metadata = StatusUpdateMetadataMapper
+                        .createStatusUpdateMetadataEntity(t, updatedBy);
+                t.setStatusUpdateMetadata(metadata);
+
+                tenantRepository.save(t);
+
+
+                UpdateStatusResponse response = UpdateStatusResponse.newBuilder()
+                        .setTenantId(id)
+                        .setStatus(request.getStatus())
+                        .build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while updating tenant status " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    private boolean isTenantExist(String domain, String name) {
+        List<Tenant> tenant = tenantRepository.findByDomainAndName(domain, name);
+        if (tenant != null && !tenant.isEmpty()) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isUpdatable(Long tenantId, String domain, String name) {
+        List<Tenant> tenantList = tenantRepository.findByDomainAndName(domain, name);
+
+//        if (tenantList != null && !tenantList.isEmpty()) {
+//            Tenant exTeant = tenantList.get(0);
+//            if (!exTeant.getId().equals(tenantId)) {
+//                return false;
+//            }
+//        }
+        Optional<Tenant> opt = tenantRepository.findById(tenantId);
+        if (opt.isPresent()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+}
+
+
+
diff --git a/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/validator/InputValidator.java b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/validator/InputValidator.java
new file mode 100644
index 0000000..2949b98
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/java/org/apache/custos/tenant/profile/validator/InputValidator.java
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.profile.validator;
+
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.tenant.profile.exceptions.MissingParameterException;
+import org.apache.custos.tenant.profile.service.*;
+
+/**
+ * This class validates the  requests
+ */
+public class InputValidator implements Validator {
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param obj
+     * @return
+     */
+    public void validate(String methodName, Object obj) {
+
+        switch (methodName) {
+            case "addTenant":
+                validateAddTenant(obj);
+                break;
+            case "updateTenant":
+                validateUpdateTenant(obj);
+                break;
+            case "getTenant":
+                validateGetTenant(obj);
+                break;
+            case "getTenantAttributeUpdateAuditTrail":
+            case "getTenantStatusUpdateAuditTrail":
+                validateGetMetadata(obj);
+                break;
+            case "updateTenantStatus":
+                validateUpdateTenantStatus(obj);
+                break;
+            case "getAllTenantsForUser":
+                validateGetAllTenantsForUser(obj);
+                break;
+            case "getAllTenants":
+                validateGetAllTenants(obj);
+                break;
+            default:
+
+        }
+
+
+    }
+
+    private boolean validateAddTenant(Object obj) {
+        if (obj instanceof Tenant) {
+            Tenant tenant = (Tenant) obj;
+
+            if (tenant.getClientName() == null || tenant.getClientName().trim() == "") {
+                throw new MissingParameterException("Client name should not be null", null);
+            }
+
+            if (tenant.getDomain() == null || tenant.getDomain().trim() == "") {
+                throw new MissingParameterException(" Domain should not be null", null);
+            }
+
+
+            if (tenant.getAdminFirstName() == null || tenant.getAdminFirstName().trim() == "") {
+                throw new MissingParameterException(" Admin first name should not be null", null);
+            }
+
+            if (tenant.getAdminLastName() == null || tenant.getAdminLastName().trim() == "") {
+                throw new MissingParameterException(" Admin last name should not be null", null);
+            }
+
+            if (tenant.getAdminEmail() == null || tenant.getAdminEmail().trim() == "") {
+                throw new MissingParameterException(" Admin email should not be null", null);
+            }
+
+            if (tenant.getAdminUsername() == null || tenant.getAdminUsername().trim() == "") {
+                throw new MissingParameterException(" Admin username should not be null", null);
+            }
+
+            if (tenant.getAdminPassword() == null || tenant.getAdminPassword().trim() == "") {
+                throw new MissingParameterException(" Admin password should not be null", null);
+            }
+
+            if (tenant.getRequesterEmail() == null || tenant.getRequesterEmail().trim() == "") {
+                throw new MissingParameterException("Admin requester email  should not be null", null);
+            }
+
+            if (tenant.getRedirectUrisCount() == 0) {
+                throw new MissingParameterException("Redirect uris cannot be  should not be null", null);
+            }
+
+            if (tenant.getJwksCount() > 0 && (tenant.getJwksUri() != null && !tenant.getJwksUri().trim().equals(""))) {
+                throw new RuntimeException("jwks and jwks both should not be present in a single request", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method addTenant");
+        }
+        return true;
+    }
+
+
+    private boolean validateUpdateTenant(Object obj) {
+        if (obj instanceof Tenant) {
+
+            Tenant tenant = (Tenant) obj;
+
+
+            if (tenant == null || tenant.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id should not be null", null);
+            }
+
+
+            if (tenant.getClientName() == null || tenant.getClientName().trim() == "") {
+                throw new MissingParameterException("Client name should not be null", null);
+            }
+
+            if (tenant.getDomain() == null || tenant.getDomain().trim() == "") {
+                throw new MissingParameterException("Tenant domain should not be null", null);
+            }
+
+
+            if (tenant.getAdminFirstName() == null || tenant.getAdminFirstName().trim() == "") {
+                throw new MissingParameterException(" Admin first name should not be null", null);
+            }
+
+            if (tenant.getAdminLastName() == null || tenant.getAdminLastName().trim() == "") {
+                throw new MissingParameterException(" Admin last name should not be null", null);
+            }
+
+            if (tenant.getAdminEmail() == null || tenant.getAdminEmail().trim() == "") {
+                throw new MissingParameterException(" Admin email should not be null", null);
+            }
+
+            if (tenant.getAdminUsername() == null || tenant.getAdminUsername().trim() == "") {
+                throw new MissingParameterException(" Admin username should not be null", null);
+            }
+
+            if (tenant.getAdminPassword() == null || tenant.getAdminPassword().trim() == "") {
+                throw new MissingParameterException(" Admin password should not be null", null);
+            }
+
+            if (tenant.getRequesterEmail() == null || tenant.getRequesterEmail().trim() == "") {
+                throw new MissingParameterException("Tenant requester email  should not be null", null);
+            }
+
+            if (tenant.getRedirectUrisCount() == 0) {
+                throw new MissingParameterException("Redirect uris cannot be  should not be null", null);
+            }
+
+            if (tenant.getJwksCount() > 0 && (tenant.getJwksUri() != null && !tenant.getJwksUri().trim().equals(""))) {
+                throw new RuntimeException("jwks and jwks both should not be present in a single request", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method updateTenant");
+        }
+        return true;
+    }
+
+
+    private boolean validateGetAllTenantsForUser(Object obj) {
+        if (obj instanceof GetAllTenantsForUserRequest) {
+            GetAllTenantsForUserRequest req = (GetAllTenantsForUserRequest) obj;
+
+            if (req.getRequesterEmail() == null || req.getRequesterEmail().trim().equals("")) {
+                throw new MissingParameterException("Requester email should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method updateTenant");
+        }
+        return true;
+    }
+
+    private boolean validateGetTenant(Object obj) {
+        if (obj instanceof GetTenantRequest) {
+            GetTenantRequest req = (GetTenantRequest) obj;
+
+            if (req.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id  should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method getTenant");
+        }
+        return true;
+    }
+
+
+    private boolean validateGetMetadata(Object obj) {
+        if (obj instanceof GetAuditTrailRequest) {
+            GetAuditTrailRequest req = (GetAuditTrailRequest) obj;
+
+            if (req.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id  should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method getMetadata");
+        }
+        return true;
+
+    }
+
+
+    private boolean validateGetAllTenants(Object obj) {
+        if (obj instanceof GetTenantsRequest) {
+            GetTenantsRequest req = (GetTenantsRequest) obj;
+
+            if (req.getLimit() == 0 && (req.getRequesterEmail() == null ||  req.getRequesterEmail().equals(""))) {
+                throw new MissingParameterException("Limit should greater than 0", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method getMetadata");
+        }
+        return true;
+
+    }
+
+
+    private boolean validateUpdateTenantStatus(Object obj) {
+        if (obj instanceof UpdateStatusRequest) {
+            UpdateStatusRequest req = (UpdateStatusRequest) obj;
+
+            if (req.getTenantId() == 0) {
+                throw new MissingParameterException("Tenant Id  should not be null", null);
+            }
+
+            if (req.getStatus() == null) {
+                throw new MissingParameterException("Tenant Status  should not be null", null);
+            }
+
+            if (req.getUpdatedBy() == null || req.getUpdatedBy().trim().equals("")) {
+                throw new MissingParameterException("Tenant UpdatedBy  should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method updateTenantStatus");
+        }
+        return true;
+
+
+    }
+
+
+}
diff --git a/custos-core-services/tenant-profile-core-service/src/main/proto/TenantProfileService.proto b/custos-core-services/tenant-profile-core-service/src/main/proto/TenantProfileService.proto
new file mode 100644
index 0000000..af4f291
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/proto/TenantProfileService.proto
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.tenant.profile.service;
+
+message Tenant {
+    int64 tenant_id = 1;
+    string client_name = 2;
+    string requester_email = 4;
+    string admin_first_name = 5;
+    string admin_last_name = 6;
+    string admin_email = 7;
+    string admin_username = 8;
+    string admin_password = 9;
+    TenantStatus tenant_status = 10;
+    repeated string contacts = 11;
+    repeated string redirect_uris = 12;
+    string client_uri = 13;
+    string scope = 14;
+    string domain = 15;
+    string comment = 16;
+    string logo_uri = 17;
+    int64 parent_tenant_id = 18;
+    string application_type = 19;
+    string token_endpoint_auth_method = 20;
+    string jwks_uri = 21;
+    string example_extension_parameter = 22;
+    string tos_uri = 23;
+    string policy_uri = 24;
+    map<string, string> jwks = 25;
+    string software_id = 26;
+    string software_version = 27;
+    int64 refesh_token_lifetime = 28;
+    string client_id = 29;
+}
+
+enum TenantStatus {
+    REQUESTED = 0;
+    APPROVED = 1;
+    DENIED = 2;
+    CANCELLED = 3;
+    ACTIVE = 4;
+    DEACTIVATED = 5;
+}
+
+message TenantAttributeUpdateMetadata {
+    string updatedAttribute = 1;
+    string updatedAttributeValue = 2;
+    string updatedBy = 3;
+    string updatedAt = 4;
+}
+
+message TenantStatusUpdateMetadata {
+    TenantStatus updatedStatus = 1;
+    string updatedBy = 2;
+    string updatedAt = 3;
+}
+
+
+message AddTenantResponse {
+    int64 tenantId = 1;
+}
+
+
+message UpdateTenantResponse {
+    Tenant tenant = 1;
+
+}
+
+message GetTenantRequest {
+    int64 tenantId = 1;
+}
+
+message GetTenantResponse {
+    Tenant tenant = 1;
+}
+
+
+message GetAllTenantsResponse {
+    repeated Tenant tenant = 1;
+}
+
+message IsTenantExistRequest {
+    int64 tenantId = 1;
+}
+
+message IsTenantExistResponse {
+    bool isExist = 1;
+}
+
+message GetAllTenantsForUserRequest {
+    string requesterEmail = 1;
+}
+
+message GetAllTenantsForUserResponse {
+    repeated Tenant tenant = 1;
+}
+
+message UpdateStatusRequest {
+    string client_id = 1;
+    TenantStatus status = 2;
+    string updatedBy = 3;
+    int64 tenantId = 4;
+    bool super_tenant = 5;
+    string accessToken = 6;
+}
+
+message UpdateStatusResponse {
+    int64 tenantId = 1;
+    TenantStatus status = 2;
+}
+
+message GetAuditTrailRequest {
+    int64 tenantId = 1;
+}
+
+message GetStatusUpdateAuditTrailResponse {
+    repeated TenantStatusUpdateMetadata metadata = 1;
+}
+
+message GetAttributeUpdateAuditTrailResponse {
+    repeated TenantAttributeUpdateMetadata metadata = 2;
+}
+
+message GetTenantsRequest {
+ int32 offset = 1;
+ int32 limit = 2;
+ int64 parent_id = 3;
+ TenantStatus status = 4;
+ string requester_email = 5;
+}
+
+service TenantProfileService {
+    rpc addTenant (Tenant) returns (Tenant);
+    rpc updateTenant (Tenant) returns (Tenant);
+    rpc getTenant (GetTenantRequest) returns (GetTenantResponse);
+    rpc updateTenantStatus (UpdateStatusRequest) returns (UpdateStatusResponse);
+    rpc getAllTenants (GetTenantsRequest) returns (GetAllTenantsResponse);
+    rpc isTenantExist (IsTenantExistRequest) returns (IsTenantExistResponse);
+    rpc getAllTenantsForUser (GetAllTenantsForUserRequest) returns (GetAllTenantsForUserResponse);
+    rpc getTenantStatusUpdateAuditTrail (GetAuditTrailRequest) returns (GetStatusUpdateAuditTrailResponse);
+    rpc getTenantAttributeUpdateAuditTrail (GetAuditTrailRequest) returns (GetAttributeUpdateAuditTrailResponse);
+}
\ No newline at end of file
diff --git a/custos-core-services/tenant-profile-core-service/src/main/resources/application.properties b/custos-core-services/tenant-profile-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..af475b5
--- /dev/null
+++ b/custos-core-services/tenant-profile-core-service/src/main/resources/application.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=tenantProfileCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_tenant?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
+
diff --git a/custos-core-services/user-profile-core-service/Dockerfile b/custos-core-services/user-profile-core-service/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/user-profile-core-service/pom.xml b/custos-core-services/user-profile-core-service/pom.xml
new file mode 100644
index 0000000..9aef334
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/pom.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>user-profile-core-service</artifactId>
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/.helmignore b/custos-core-services/user-profile-core-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/Chart.yaml b/custos-core-services/user-profile-core-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..9683274
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm chart of custos user profile service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/templates/NOTES.txt b/custos-core-services/user-profile-core-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/user-profile-core-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/templates/deployment.yaml b/custos-core-services/user-profile-core-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..31e54a6
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,64 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 8080
+              protocol: TCP
+            - name: grpc
+              containerPort: 7000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 8080
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/templates/ingress.yaml b/custos-core-services/user-profile-core-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/templates/service.yaml b/custos-core-services/user-profile-core-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..a8df80d
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.gRPCPort }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/user-profile-core-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/user-profile-core-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/user-profile-core-service/src/main/helm/values.yaml b/custos-core-services/user-profile-core-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..fa8b2ef
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/helm/values.yaml
@@ -0,0 +1,79 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  gRPCPort: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/UserProfileServiceInitializer.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/UserProfileServiceInitializer.java
new file mode 100644
index 0000000..b5b3792
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/UserProfileServiceInitializer.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.apache.custos.user.profile.service.UserProfileService;
+import org.apache.custos.user.profile.validators.InputValidator;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+
+@SpringBootApplication
+@EnableJpaAuditing
+public class UserProfileServiceInitializer {
+
+
+    public static void main(String[] args) {
+        SpringApplication.run(UserProfileServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        return GrpcTracing.create(tracing);
+    }
+
+    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
+    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public InputValidator getValidator() {
+        return new InputValidator();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(InputValidator validator) {
+        return new ServiceInterceptor(validator);
+    }
+
+    @Bean
+    public boolean initialize(UserProfileService service) {
+        return service.initializeDBConfigs();
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/AttributeUpdateMetadataMapper.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/AttributeUpdateMetadataMapper.java
new file mode 100644
index 0000000..f56f37c
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/AttributeUpdateMetadataMapper.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.mapper;
+
+
+import org.apache.custos.user.profile.persistance.model.AttributeUpdateMetadata;
+import org.apache.custos.user.profile.persistance.model.UserProfile;
+import org.apache.custos.user.profile.service.UserProfileAttributeUpdateMetadata;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class maps attributes between grpc TenantAttributeUpdateMetadata to DB AttributeUpdateMetadata table
+ */
+public class AttributeUpdateMetadataMapper {
+
+
+    /**
+     * This creates Attribute update entity List from comparing oldTenant and newTenant
+     *
+     * @param updatedBy
+     * @return
+     */
+    public static Set<AttributeUpdateMetadata> createAttributeUpdateMetadataEntity(UserProfile oldProf, UserProfile newProf, String updatedBy) {
+
+        Set<AttributeUpdateMetadata> metadataSet = new HashSet<>();
+        if (!(oldProf.getTenantId() == newProf.getTenantId())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setUserProfile(newProf);
+            attributeUpdateMetadata.setUpdatedFieldKey("tenanId");
+            attributeUpdateMetadata.setUpdatedFieldValue(String.valueOf(newProf.getTenantId()));
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldProf.getUsername().equals(newProf.getUsername())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setUserProfile(newProf);
+            attributeUpdateMetadata.setUpdatedFieldKey("username");
+            attributeUpdateMetadata.setUpdatedFieldValue(newProf.getUsername());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldProf.getEmailAddress().equals(newProf.getEmailAddress())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setUserProfile(newProf);
+            attributeUpdateMetadata.setUpdatedFieldKey("emailAddress");
+            attributeUpdateMetadata.setUpdatedFieldValue(newProf.getEmailAddress());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldProf.getFirstName().equals(newProf.getFirstName())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setUserProfile(newProf);
+            attributeUpdateMetadata.setUpdatedFieldKey("firstName");
+            attributeUpdateMetadata.setUpdatedFieldValue(newProf.getFirstName());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        if (!oldProf.getLastName().equals(newProf.getLastName())) {
+            AttributeUpdateMetadata attributeUpdateMetadata = new AttributeUpdateMetadata();
+            attributeUpdateMetadata.setUserProfile(newProf);
+            attributeUpdateMetadata.setUpdatedFieldKey("lastName");
+            attributeUpdateMetadata.setUpdatedFieldValue(newProf.getLastName());
+            attributeUpdateMetadata.setUpdatedBy(updatedBy);
+            metadataSet.add(attributeUpdateMetadata);
+        }
+
+        return metadataSet;
+    }
+
+
+    /**
+     * create attribute update metadata from db entity
+     *
+     * @param metadata
+     * @return
+     */
+    public static UserProfileAttributeUpdateMetadata createAttributeUpdateMetadataFromEntity(AttributeUpdateMetadata metadata) {
+
+        return UserProfileAttributeUpdateMetadata.newBuilder()
+                .setUpdatedAt(metadata.getUpdatedAt().toString())
+                .setUpdatedBy(metadata.getUpdatedBy())
+                .setUpdatedAttributeValue(metadata.getUpdatedFieldValue())
+                .setUpdatedAttribute(metadata.getUpdatedFieldKey())
+                .build();
+    }
+
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/GroupMapper.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/GroupMapper.java
new file mode 100644
index 0000000..6cd8c5f
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/GroupMapper.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.mapper;
+
+import org.apache.custos.user.profile.persistance.model.Group;
+import org.apache.custos.user.profile.persistance.model.GroupAttribute;
+import org.apache.custos.user.profile.persistance.model.GroupRole;
+import org.apache.custos.user.profile.persistance.model.GroupToGroupMembership;
+import org.apache.custos.user.profile.utils.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+/**
+ * This class maps persistence data model to gRPC data model
+ */
+public class GroupMapper {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(GroupMapper.class);
+
+
+    public static Group createGroupEntity(org.apache.custos.user.profile.service.Group group, long tenantId) {
+
+        Group groupEntity = new Group();
+        String id = group.getId() + "@" + tenantId;
+
+        String parentId = group.getParentId();
+
+        if (parentId != null && !parentId.trim().equals("")) {
+            parentId = group.getParentId() + "@" + tenantId;
+        }
+
+        groupEntity.setId(id);
+        groupEntity.setExternalId(group.getId());
+        groupEntity.setName(group.getName());
+        groupEntity.setTenantId(tenantId);
+        groupEntity.setParentId(parentId);
+
+
+
+        if (group.getDescription() != null && !group.getDescription().trim().equals("")) {
+            groupEntity.setDescription(group.getDescription());
+        }
+
+        Set<GroupAttribute> groupList = new HashSet<>();
+        if (!group.getAttributesList().isEmpty()) {
+
+
+            group.getAttributesList().forEach(atr -> {
+
+                for (String value : atr.getValueList()) {
+                    GroupAttribute groupAttribute = new GroupAttribute();
+                    groupAttribute.setKeyValue(atr.getKey());
+                    groupAttribute.setValue(value);
+                    groupAttribute.setGroup(groupEntity);
+                    groupList.add(groupAttribute);
+
+                }
+
+            });
+
+
+
+        }
+        groupEntity.setGroupAttribute(groupList);
+
+        Set<GroupRole> groupRoles = new HashSet<>();
+
+        if (!group.getClientRolesList().isEmpty()) {
+
+
+            group.getClientRolesList().forEach(role -> {
+
+                GroupRole userRole = new GroupRole();
+                userRole.setValue(role);
+                userRole.setType(Constants.ROLE_TYPE_CLIENT);
+                userRole.setGroup(groupEntity);
+                groupRoles.add(userRole);
+
+            });
+
+
+        }
+
+
+        if (!group.getRealmRolesList().isEmpty()) {
+
+            group.getRealmRolesList().forEach(role -> {
+
+                GroupRole userRole = new GroupRole();
+                userRole.setValue(role);
+                userRole.setType(Constants.ROLE_TYPE_REALM);
+                userRole.setGroup(groupEntity);
+                groupRoles.add(userRole);
+
+            });
+
+        }
+
+        groupEntity.setGroupRole(groupRoles);
+
+
+        return groupEntity;
+    }
+
+
+    public static org.apache.custos.user.profile.service.Group createGroup(Group group, String ownerId) {
+
+        org.apache.custos.user.profile.service.Group.Builder groupBuilder = org.apache.custos.user.profile.service.Group
+                .newBuilder()
+                .setId(group.getExternalId())
+                .setName(group.getName())
+                .setParentId(group.getParentId())
+                .setCreatedTime(group.getCreatedAt().getTime())
+                .setLastModifiedTime(group.getLastModifiedAt().getTime())
+                .setOwnerId(ownerId);
+
+
+        if (group.getDescription() != null) {
+            groupBuilder.setDescription(group.getDescription());
+        }
+
+        List<String> clientRoles = new ArrayList<>();
+        List<String> realmRoles = new ArrayList<>();
+
+        if (group.getGroupRole() != null && !group.getGroupRole().isEmpty()) {
+
+            group.getGroupRole().forEach(role -> {
+                if (role.getType().equals(Constants.ROLE_TYPE_CLIENT)) {
+                    clientRoles.add(role.getValue());
+                } else {
+                    realmRoles.add(role.getValue());
+                }
+            });
+        }
+
+        List<org.apache.custos.user.profile.service.GroupAttribute> attributeList = new ArrayList<>();
+        Map<String, List<String>> atrMap = new HashMap<>();
+        if (group.getGroupAttribute() != null && !group.getGroupAttribute().isEmpty()) {
+
+            group.getGroupAttribute().forEach(atr -> {
+
+                if (atrMap.get(atr.getKeyValue()) == null) {
+                    atrMap.put(atr.getKeyValue(), new ArrayList<String>());
+                }
+                atrMap.get(atr.getKeyValue()).add(atr.getValue());
+
+            });
+
+            groupBuilder = groupBuilder.addAllClientRoles(clientRoles).addAllRealmRoles(realmRoles);
+        }
+
+        atrMap.keySet().forEach(key -> {
+            org.apache.custos.user.profile.service.GroupAttribute attribute = org.apache.custos.user.profile.service
+                    .GroupAttribute
+                    .newBuilder()
+                    .setKey(key)
+                    .addAllValue(atrMap.get(key))
+                    .build();
+            attributeList.add(attribute);
+        });
+
+        return groupBuilder.addAllAttributes(attributeList).build();
+
+    }
+
+
+    public static Group setParentGroupMembership(Group parent, Group child) {
+
+        GroupToGroupMembership groupToGroupMembership = new GroupToGroupMembership();
+        groupToGroupMembership.setChild(child);
+        groupToGroupMembership.setParent(parent);
+        groupToGroupMembership.setTenantId(child.getTenantId());
+
+
+        Set<GroupToGroupMembership> groupList = new HashSet<>();
+        groupList.add(groupToGroupMembership);
+        child.setParentGroups(groupList);
+        return child;
+
+    }
+
+    public static GroupToGroupMembership groupToGroupMembership(Group child, Group parent) {
+        GroupToGroupMembership groupToGroupMembership = new GroupToGroupMembership();
+        groupToGroupMembership.setChild(child);
+        groupToGroupMembership.setParent(parent);
+        groupToGroupMembership.setTenantId(child.getTenantId());
+        return groupToGroupMembership;
+
+    }
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/StatusUpdateMetadataMapper.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/StatusUpdateMetadataMapper.java
new file mode 100644
index 0000000..994b0b1
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/StatusUpdateMetadataMapper.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.mapper;
+
+
+import org.apache.custos.user.profile.persistance.model.StatusUpdateMetadata;
+import org.apache.custos.user.profile.persistance.model.UserProfile;
+import org.apache.custos.user.profile.service.UserProfileStatusUpdateMetadata;
+import org.apache.custos.user.profile.service.UserStatus;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class maps attributes of grpc UserProfileStatusUpdateMetadata to DB StatusUpdateMetadata table
+ */
+public class StatusUpdateMetadataMapper {
+
+
+    /**
+     * Creates Status update entity to save in DB
+     *
+     * @param {@link    org.apache.custos.user.profile.UserProfile} profile
+     * @param updatedBy
+     * @return
+     */
+    public static Set<StatusUpdateMetadata> createStatusUpdateMetadataEntity(UserProfile tenant, String updatedBy) {
+
+        Set<StatusUpdateMetadata> metaDataSet = new HashSet<>();
+
+        StatusUpdateMetadata metadata = new StatusUpdateMetadata();
+        metadata.setUserProfile(tenant);
+        metadata.setUpdatedBy(updatedBy);
+        metadata.setUpdatedStatus(tenant.getStatus());
+
+        metaDataSet.add(metadata);
+        return metaDataSet;
+
+    }
+
+    /**
+     * convert TenantStatusUpdateMetadataEntity to gRPC TenantStatusUpdateMetadata
+     *
+     * @param metadata
+     * @return TenantStatusUpdateMetadata
+     */
+    public static UserProfileStatusUpdateMetadata createUserProfileStatusMetadataFrom(StatusUpdateMetadata metadata) {
+        return UserProfileStatusUpdateMetadata.newBuilder()
+                .setUpdatedAt(metadata.getUpdatedAt().toString())
+                .setUpdatedBy(metadata.getUpdatedBy())
+                .setUpdatedStatus(UserStatus.valueOf(metadata.getUpdatedStatus())).build();
+
+    }
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/UserProfileMapper.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/UserProfileMapper.java
new file mode 100644
index 0000000..2e13a1e
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/mapper/UserProfileMapper.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.mapper;
+
+
+import org.apache.custos.user.profile.persistance.model.UserAttribute;
+import org.apache.custos.user.profile.persistance.model.UserProfile;
+import org.apache.custos.user.profile.persistance.model.UserRole;
+import org.apache.custos.user.profile.service.DefaultGroupMembershipTypes;
+import org.apache.custos.user.profile.service.UserStatus;
+import org.apache.custos.user.profile.service.UserTypes;
+import org.apache.custos.user.profile.utils.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+
+/**
+ * This class maps attributes between grpc UserProfile to DB UserProfile table
+ */
+public class UserProfileMapper {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserProfileMapper.class);
+
+    /**
+     * Maps gRPC UserProfile Model to DB Layer UserProfile Entity
+     *
+     * @param {@link org.apache.custos.user.profile.service.UserProfile} tenant
+     * @return Tenant
+     */
+    public static UserProfile createUserProfileEntityFromUserProfile(org.apache.custos.user.profile.service.UserProfile userProfile) {
+
+        UserProfile entity = new UserProfile();
+
+        entity.setUsername(userProfile.getUsername());
+        if (userProfile.getEmail() != null && !userProfile.getEmail().trim().equals("")) {
+            entity.setEmailAddress(userProfile.getEmail());
+        }
+
+        if (userProfile.getFirstName() != null && !userProfile.getFirstName().trim().equals("")) {
+            entity.setFirstName(userProfile.getFirstName());
+        }
+
+        if (userProfile.getLastName() != null && !userProfile.getLastName().trim().equals("")) {
+            entity.setLastName(userProfile.getLastName());
+        }
+
+        if (userProfile.getType() != null) {
+            entity.setType(userProfile.getType().name());
+        } else {
+            entity.setType(UserTypes.END_USER.name());
+        }
+
+        entity.setStatus(userProfile.getStatus().name());
+
+        Set<UserAttribute> attributeSet = new HashSet<>();
+        if (userProfile.getAttributesList() != null && !userProfile.getAttributesList().isEmpty()) {
+
+
+            userProfile.getAttributesList().forEach(atr -> {
+                if (atr.getValueList() != null && !atr.getValueList().isEmpty()) {
+                    for (String value : atr.getValueList()) {
+                        UserAttribute userAttribute = new UserAttribute();
+                        userAttribute.setKey(atr.getKey());
+                        userAttribute.setValue(value);
+                        userAttribute.setUserProfile(entity);
+                        attributeSet.add(userAttribute);
+                    }
+                }
+
+            });
+
+
+        }
+        entity.setUserAttribute(attributeSet);
+        Set<UserRole> userRoleSet = new HashSet<>();
+        if (userProfile.getRealmRolesList() != null && !userProfile.getRealmRolesList().isEmpty()) {
+
+
+            userProfile.getRealmRolesList().forEach(role -> {
+                UserRole userRole = new UserRole();
+                userRole.setValue(role);
+                userRole.setType(Constants.ROLE_TYPE_REALM);
+                userRole.setUserProfile(entity);
+                userRoleSet.add(userRole);
+            });
+
+
+        }
+
+        if (userProfile.getClientRolesList() != null && !userProfile.getClientRolesList().isEmpty()) {
+            userProfile.getClientRolesList().forEach(role -> {
+                UserRole userRole = new UserRole();
+                userRole.setValue(role);
+                userRole.setType(Constants.ROLE_TYPE_CLIENT);
+                userRole.setUserProfile(entity);
+                userRoleSet.add(userRole);
+            });
+
+
+        }
+        entity.setUserRole(userRoleSet);
+
+        return entity;
+    }
+
+
+    /**
+     * Transform UserProfileEntity to Tenant
+     *
+     * @param profileEntity
+     * @return tenant
+     */
+    public static org.apache.custos.user.profile.service.UserProfile createUserProfileFromUserProfileEntity(UserProfile profileEntity, String membershipType) {
+
+
+        org.apache.custos.user.profile.service.UserProfile.Builder builder =
+                org.apache.custos.user.profile.service.UserProfile.newBuilder();
+
+
+        if (profileEntity.getUserRole() != null && !profileEntity.getUserRole().isEmpty()) {
+
+            profileEntity.getUserRole().forEach(role -> {
+                if (role.getType().equals(Constants.ROLE_TYPE_CLIENT)) {
+                    builder.addClientRoles(role.getValue());
+                } else {
+                    builder.addRealmRoles(role.getValue());
+                }
+            });
+        }
+
+        List<org.apache.custos.user.profile.service.UserAttribute> attributeList = new ArrayList<>();
+        if (profileEntity.getUserAttribute() != null && !profileEntity.getUserAttribute().isEmpty()) {
+
+            Map<String, List<String>> atrMap = new HashMap<>();
+
+            profileEntity.getUserAttribute().forEach(atr -> {
+
+                if (atrMap.get(atr.getKey()) == null) {
+                    atrMap.put(atr.getKey(), new ArrayList<String>());
+                }
+                atrMap.get(atr.getKey()).add(atr.getValue());
+
+            });
+
+
+            atrMap.keySet().forEach(key -> {
+                org.apache.custos.user.profile.service.UserAttribute attribute = org.apache.custos.user.profile.service
+                        .UserAttribute
+                        .newBuilder()
+                        .setKey(key)
+                        .addAllValue(atrMap.get(key))
+                        .build();
+                attributeList.add(attribute);
+            });
+        }
+
+
+        builder
+                .setUsername(profileEntity.getUsername())
+                .setCreatedAt(profileEntity.getCreatedAt().getTime())
+                .setLastModifiedAt(profileEntity.getLastModifiedAt() != null ? profileEntity.getLastModifiedAt().getTime() : 0)
+                .setStatus(UserStatus.valueOf(profileEntity.getStatus()))
+                .addAllAttributes(attributeList);
+
+
+        if (profileEntity.getEmailAddress() != null) {
+            builder.setEmail(profileEntity.getEmailAddress());
+        }
+
+        if (profileEntity.getFirstName() != null) {
+            builder.setFirstName(profileEntity.getFirstName());
+        }
+
+        if (profileEntity.getLastName() != null) {
+            builder.setLastName(profileEntity.getLastName());
+        }
+
+        if (membershipType != null ) {
+            builder.setMembershipType(DefaultGroupMembershipTypes.valueOf(membershipType));
+        }
+
+        if (profileEntity.getType() == null) {
+            builder.setType(UserTypes.END_USER);
+        } else {
+            builder.setType(UserTypes.valueOf(profileEntity.getType()));
+        }
+
+        return builder.build();
+
+
+    }
+
+
+    public static String getUserInfoInfoAsString(org.apache.custos.user.profile.service.UserProfile userProfile) {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("username : " + userProfile.getUsername());
+        buffer.append("\n");
+        buffer.append("emailAddress : " + userProfile.getEmail());
+        buffer.append("\n");
+        buffer.append("firstName : " + userProfile.getFirstName());
+        buffer.append("\n");
+        buffer.append("lastName : " + userProfile.getLastName());
+        buffer.append("\n");
+
+        return buffer.toString();
+
+    }
+
+
+}
+
+
+
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/AttributeUpdateMetadata.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/AttributeUpdateMetadata.java
new file mode 100644
index 0000000..ed1a829
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/AttributeUpdateMetadata.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Keeps track of attribute updated metadata
+ */
+@Entity
+@Table(name = "attribute_update_metadata")
+@EntityListeners(AuditingEntityListener.class)
+public class AttributeUpdateMetadata {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String updatedFieldKey;
+
+    @Column(nullable = false)
+    private String updatedFieldValue;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date updatedAt;
+
+    @Column(nullable = false)
+    private String updatedBy;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "user_profile_id")
+    private UserProfile userProfile;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUpdatedFieldKey() {
+        return updatedFieldKey;
+    }
+
+    public void setUpdatedFieldKey(String updatedFieldKey) {
+        this.updatedFieldKey = updatedFieldKey;
+    }
+
+    public String getUpdatedFieldValue() {
+        return updatedFieldValue;
+    }
+
+    public void setUpdatedFieldValue(String updatedFieldValue) {
+        this.updatedFieldValue = updatedFieldValue;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public String getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(String updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public UserProfile getUserProfile() {
+        return userProfile;
+    }
+
+    public void setUserProfile(UserProfile userProfile) {
+        this.userProfile = userProfile;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/Group.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/Group.java
new file mode 100644
index 0000000..c8f2961
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/Group.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * Group Entity
+ */
+@Entity
+@Table(name = "group_entity")
+@EntityListeners(AuditingEntityListener.class)
+public class Group {
+
+    @Id
+    private String id;
+
+    @Column(nullable = false)
+    private Long tenantId;
+
+    @Column(nullable = false)
+    private String name;
+
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedAt;
+
+    @Column
+    private String parentId;
+
+     @Column
+    private String  externalId;
+
+     @Column
+     private String description;
+
+
+
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "group", orphanRemoval = true, cascade = CascadeType.ALL)
+    private Set<GroupRole> groupRole;
+
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "group", orphanRemoval = true, cascade = CascadeType.ALL)
+    private Set<GroupAttribute> groupAttribute;
+
+
+    @OneToMany(mappedBy = "group", cascade = CascadeType.ALL)
+    Set<UserGroupMembership> userGroupMemberships;
+
+    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
+    Set<GroupToGroupMembership> parentGroups;
+
+    @OneToMany(mappedBy = "child", cascade = CascadeType.ALL)
+    Set<GroupToGroupMembership> childGroups;
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public Set<UserGroupMembership> getUserGroupMemberships() {
+        return userGroupMemberships;
+    }
+
+    public void setUserGroupMemberships(Set<UserGroupMembership> userGroupMemberships) {
+        this.userGroupMemberships = userGroupMemberships;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Date getLastModifiedAt() {
+        return lastModifiedAt;
+    }
+
+    public void setLastModifiedAt(Date lastModifiedAt) {
+        this.lastModifiedAt = lastModifiedAt;
+    }
+
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    public Set<GroupRole> getGroupRole() {
+        return groupRole;
+    }
+
+    public void setGroupRole(Set<GroupRole> groupRole) {
+        this.groupRole = groupRole;
+    }
+
+    public Set<GroupAttribute> getGroupAttribute() {
+        return groupAttribute;
+    }
+
+    public void setGroupAttribute(Set<GroupAttribute> groupAttribute) {
+        this.groupAttribute = groupAttribute;
+    }
+
+    public Set<GroupToGroupMembership> getParentGroups() {
+        return parentGroups;
+    }
+
+    public void setParentGroups(Set<GroupToGroupMembership> parentGroups) {
+        this.parentGroups = parentGroups;
+    }
+
+    public Set<GroupToGroupMembership> getChildGroups() {
+        return childGroups;
+    }
+
+    public void setChildGroups(Set<GroupToGroupMembership> childGroups) {
+        this.childGroups = childGroups;
+    }
+
+    public String getExternalId() {
+        return externalId;
+    }
+
+    public void setExternalId(String externalId) {
+        this.externalId = externalId;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/GroupAttribute.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/GroupAttribute.java
new file mode 100644
index 0000000..bb72920
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/GroupAttribute.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import javax.persistence.*;
+
+/**
+ * Group attribute
+ */
+
+@Entity
+@Table(name = "group_attribute")
+public class GroupAttribute {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String keyValue;
+
+    @Column(nullable = false)
+    private String value;
+
+    @ManyToOne
+    @JoinColumn(name = "group_entity_id")
+    private Group group;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getKeyValue() {
+        return keyValue;
+    }
+
+    public void setKeyValue(String keyValue) {
+        this.keyValue = keyValue;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public Group getGroup() {
+        return group;
+    }
+
+    public void setGroup(Group group) {
+        this.group = group;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/GroupRole.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/GroupRole.java
new file mode 100644
index 0000000..895cb4a
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/GroupRole.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import javax.persistence.*;
+
+/**
+ * Group roles
+ */
+@Entity
+@Table(name = "group_role")
+public class GroupRole {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String type;
+
+    @Column(nullable = false)
+    private String value;
+
+    @ManyToOne
+    @JoinColumn(name = "group_entity_id")
+    private Group group;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public Group getGroup() {
+        return group;
+    }
+
+    public void setGroup(Group group) {
+        this.group = group;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/GroupToGroupMembership.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/GroupToGroupMembership.java
new file mode 100644
index 0000000..ffddc4b
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/GroupToGroupMembership.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+@Entity
+@Table(name = "group_to_group_membership")
+@EntityListeners(AuditingEntityListener.class)
+public class GroupToGroupMembership {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @ManyToOne
+    @JoinColumn(name = "parent_id")
+    Group parent;
+
+    @ManyToOne
+    @JoinColumn(name = "child_id")
+    Group child;
+
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedDate;
+
+    @Column(nullable = false)
+    private Long tenantId;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Group getParent() {
+        return parent;
+    }
+
+    public void setParent(Group parent) {
+        this.parent = parent;
+    }
+
+    public Group getChild() {
+        return child;
+    }
+
+    public void setChild(Group child) {
+        this.child = child;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLastModifiedDate() {
+        return lastModifiedDate;
+    }
+
+    public void setLastModifiedDate(Date lastModifiedDate) {
+        this.lastModifiedDate = lastModifiedDate;
+    }
+
+    public Long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Long tenantId) {
+        this.tenantId = tenantId;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/StatusUpdateMetadata.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/StatusUpdateMetadata.java
new file mode 100644
index 0000000..45dcc13
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/StatusUpdateMetadata.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Keeps the track of status updated metadata
+ */
+@Entity
+@Table(name = "status_update_metadata")
+@EntityListeners(AuditingEntityListener.class)
+public class StatusUpdateMetadata {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String updatedStatus;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date updatedAt;
+
+    @Column(nullable = false)
+    private String updatedBy;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "user_profile_id")
+    private UserProfile userProfile;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUpdatedStatus() {
+        return updatedStatus;
+    }
+
+    public void setUpdatedStatus(String updatedStatus) {
+        this.updatedStatus = updatedStatus;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+
+    public String getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(String updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public UserProfile getUserProfile() {
+        return userProfile;
+    }
+
+    public void setUserProfile(UserProfile userProfile) {
+        this.userProfile = userProfile;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserAttribute.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserAttribute.java
new file mode 100644
index 0000000..4ea49b8
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserAttribute.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "user_attribute")
+public class UserAttribute {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String keyValue;
+
+    @Column(nullable = false)
+    private String value;
+
+    @ManyToOne
+    @JoinColumn(name = "user_profile_id")
+    private UserProfile userProfile;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getKey() {
+        return keyValue;
+    }
+
+    public void setKey(String key) {
+        this.keyValue = key;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public UserProfile getUserProfile() {
+        return userProfile;
+    }
+
+    public void setUserProfile(UserProfile userProfile) {
+        this.userProfile = userProfile;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserGroupMembership.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserGroupMembership.java
new file mode 100644
index 0000000..4a6c36b
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserGroupMembership.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "user_group_membership")
+@EntityListeners(AuditingEntityListener.class)
+public class UserGroupMembership {
+
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @ManyToOne
+    @JoinColumn(name = "group_entity_id")
+    Group group;
+
+    @ManyToOne
+    @JoinColumn(name = "user_profile_id")
+    UserProfile userProfile;
+
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedDate;
+
+    @Column(nullable = false)
+    private Long tenantId;
+
+    @ManyToOne
+    @JoinColumn(name = "user_group_membership_type_id")
+    private UserGroupMembershipType userGroupMembershipType;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Group getGroup() {
+        return group;
+    }
+
+    public void setGroup(Group group) {
+        this.group = group;
+    }
+
+    public UserProfile getUserProfile() {
+        return userProfile;
+    }
+
+    public void setUserProfile(UserProfile userProfile) {
+        this.userProfile = userProfile;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLastModifiedDate() {
+        return lastModifiedDate;
+    }
+
+    public void setLastModifiedDate(Date lastModifiedDate) {
+        this.lastModifiedDate = lastModifiedDate;
+    }
+
+    public Long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public UserGroupMembershipType getUserGroupMembershipType() {
+        return userGroupMembershipType;
+    }
+
+    public void setUserGroupMembershipType(UserGroupMembershipType userGroupMembershipType) {
+        this.userGroupMembershipType = userGroupMembershipType;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserGroupMembershipType.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserGroupMembershipType.java
new file mode 100644
index 0000000..15826a4
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserGroupMembershipType.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.Set;
+
+
+/**
+ * Group Membership Type
+ */
+@Entity
+@Table(name = "user_group_membership_type")
+@EntityListeners(AuditingEntityListener.class)
+public class UserGroupMembershipType {
+
+    @Id
+    @Column(name = "id")
+    private String id;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedDate;
+
+    @OneToMany(mappedBy = "userGroupMembershipType", cascade = CascadeType.ALL)
+    Set<UserGroupMembership> memberships;
+
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getLastModifiedDate() {
+        return lastModifiedDate;
+    }
+
+    public void setLastModifiedDate(Date lastModifiedDate) {
+        this.lastModifiedDate = lastModifiedDate;
+    }
+
+    public Set<UserGroupMembership> getMemberships() {
+        return memberships;
+    }
+
+    public void setMemberships(Set<UserGroupMembership> memberships) {
+        this.memberships = memberships;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserProfile.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserProfile.java
new file mode 100644
index 0000000..0699c93
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserProfile.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * User profile entity model
+ */
+@Entity
+@Table(name = "user_profile")
+@EntityListeners(AuditingEntityListener.class)
+public class UserProfile {
+
+    @Id
+    private String id;
+
+    @Column(nullable = false)
+    private Long tenantId;
+
+    @Column(nullable = false)
+    private String username;
+
+    @Column
+    private String emailAddress;
+
+    @Column
+    private String firstName;
+
+    @Column
+    private String lastName;
+
+    @Column(nullable = false)
+    private String status;
+
+    @Column(nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    @CreatedDate
+    private Date createdAt;
+
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @LastModifiedDate
+    private Date lastModifiedAt;
+
+
+    @Column
+    private String type;
+
+
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "userProfile", orphanRemoval = true, cascade = CascadeType.ALL)
+    private Set<UserRole> userRole;
+
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "userProfile", orphanRemoval = true, cascade = CascadeType.ALL)
+    private Set<UserAttribute> userAttribute;
+
+    @OneToMany(mappedBy = "userProfile", cascade = CascadeType.ALL)
+    private Set<AttributeUpdateMetadata> attributeUpdateMetadata;
+
+    @OneToMany(mappedBy = "userProfile", cascade = CascadeType.ALL)
+    private Set<StatusUpdateMetadata> statusUpdateMetadata;
+
+
+    @OneToMany(mappedBy = "userProfile", cascade = CascadeType.ALL)
+    Set<UserGroupMembership> userGroupMemberships;
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getEmailAddress() {
+        return emailAddress;
+    }
+
+    public void setEmailAddress(String emailAddress) {
+        this.emailAddress = emailAddress;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+
+    public Set<AttributeUpdateMetadata> getAttributeUpdateMetadata() {
+        return attributeUpdateMetadata;
+    }
+
+    public void setAttributeUpdateMetadata(Set<AttributeUpdateMetadata> attributeUpdateMetadata) {
+        this.attributeUpdateMetadata = attributeUpdateMetadata;
+    }
+
+    public Set<StatusUpdateMetadata> getStatusUpdateMetadata() {
+        return statusUpdateMetadata;
+    }
+
+    public void setStatusUpdateMetadata(Set<StatusUpdateMetadata> statusUpdateMetadata) {
+        this.statusUpdateMetadata = statusUpdateMetadata;
+    }
+
+    public Set<UserAttribute> getUserAttribute() {
+        return userAttribute;
+    }
+
+    public void setUserAttribute(Set<UserAttribute> userAttribute) {
+        this.userAttribute = userAttribute;
+    }
+
+    public Set<UserRole> getUserRole() {
+        return userRole;
+    }
+
+    public void setUserRole(Set<UserRole> userRole) {
+        this.userRole = userRole;
+    }
+
+    public Set<UserGroupMembership> getUserGroupMemberships() {
+        return userGroupMemberships;
+    }
+
+    public void setUserGroupMemberships(Set<UserGroupMembership> userGroupMemberships) {
+        this.userGroupMemberships = userGroupMemberships;
+    }
+
+
+    public Date getLastModifiedAt() {
+        return lastModifiedAt;
+    }
+
+    public void setLastModifiedAt(Date lastModifiedAt) {
+        this.lastModifiedAt = lastModifiedAt;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserRole.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserRole.java
new file mode 100644
index 0000000..5daaf07
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/model/UserRole.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.model;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "user_role")
+public class UserRole {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @Column(nullable = false)
+    private String type;
+
+    @Column(nullable = false)
+    private String value;
+
+    @ManyToOne
+    @JoinColumn(name = "user_profile_id")
+    private UserProfile userProfile;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public UserProfile getUserProfile() {
+        return userProfile;
+    }
+
+    public void setUserProfile(UserProfile userProfile) {
+        this.userProfile = userProfile;
+    }
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/AttributeUpdateMetadataRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/AttributeUpdateMetadataRepository.java
new file mode 100644
index 0000000..c3365dd
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/AttributeUpdateMetadataRepository.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.AttributeUpdateMetadata;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface AttributeUpdateMetadataRepository extends JpaRepository<AttributeUpdateMetadata, Long> {
+
+    public List<AttributeUpdateMetadata> findAllByUserProfileId(String userId);
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupAttributeRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupAttributeRepository.java
new file mode 100644
index 0000000..4e9e1a8
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupAttributeRepository.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.GroupAttribute;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface GroupAttributeRepository extends JpaRepository<GroupAttribute, Long> {
+
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupMembershipRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupMembershipRepository.java
new file mode 100644
index 0000000..0220fd1
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupMembershipRepository.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.UserGroupMembership;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface GroupMembershipRepository extends JpaRepository<UserGroupMembership, String> {
+
+
+    public List<UserGroupMembership> findAllByGroupId(String id);
+
+    public List<UserGroupMembership> findAllByUserProfileId(String id);
+
+    public List<UserGroupMembership> findAllByGroupIdAndUserProfileId(String groupEntityId, String userProfileId);
+
+    public List<UserGroupMembership>
+    findAllByGroupIdAndUserProfileIdAndUserGroupMembershipTypeId(String groupId, String userProfileId, String groupMembershipId);
+
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupMembershipTypeRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupMembershipTypeRepository.java
new file mode 100644
index 0000000..feafa80
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupMembershipTypeRepository.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.UserGroupMembershipType;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface GroupMembershipTypeRepository extends JpaRepository<UserGroupMembershipType, String> {
+
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupRepository.java
new file mode 100644
index 0000000..d7a534c
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupRepository.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.Group;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface GroupRepository extends JpaRepository<Group, String> {
+
+
+    public List<Group> findByParentId(String s);
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupRoleRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupRoleRepository.java
new file mode 100644
index 0000000..acbd1f6
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupRoleRepository.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.GroupRole;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface GroupRoleRepository extends JpaRepository<GroupRole,Long> {
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupToGroupMembershipRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupToGroupMembershipRepository.java
new file mode 100644
index 0000000..a872011
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/GroupToGroupMembershipRepository.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.GroupToGroupMembership;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface GroupToGroupMembershipRepository extends JpaRepository<GroupToGroupMembership, String> {
+
+    public List<GroupToGroupMembership> findByChildIdAndParentId(String childId, String parentId);
+
+    public List<GroupToGroupMembership> findAllByChildId(String childId);
+
+    public List<GroupToGroupMembership> findAllByParentId(String parentId);
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/RoleRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/RoleRepository.java
new file mode 100644
index 0000000..fc5a465
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/RoleRepository.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.UserRole;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface RoleRepository extends JpaRepository<UserRole,Long> {
+
+    @Transactional
+    public void deleteAllByUserProfileId(String  userProfileEntityId);
+
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/StatusUpdateMetadataRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/StatusUpdateMetadataRepository.java
new file mode 100644
index 0000000..2bdebe2
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/StatusUpdateMetadataRepository.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.StatusUpdateMetadata;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface StatusUpdateMetadataRepository extends JpaRepository<StatusUpdateMetadata, Long> {
+
+
+    public List<StatusUpdateMetadata> findAllByUserProfileId(String  userId);
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/UserAttributeRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/UserAttributeRepository.java
new file mode 100644
index 0000000..acf097b
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/UserAttributeRepository.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.UserAttribute;
+import org.apache.custos.user.profile.persistance.model.UserProfile;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+public interface UserAttributeRepository extends JpaRepository<UserAttribute, Long> {
+
+    @Transactional
+    public void deleteAllByUserProfileId(String userProfileEntityId);
+
+    public List<UserAttribute> findAllByUserProfileId(String userProfileEntityId);
+
+    @Query("SELECT DISTINCT atr.userProfile from UserAttribute atr where atr.keyValue = ?1 and atr.value =?2")
+    public List<UserProfile> findFilteredUserProfiles(String key, String value);
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/UserRepository.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/UserRepository.java
new file mode 100644
index 0000000..52b85a8
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/persistance/repository/UserRepository.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.persistance.repository;
+
+import org.apache.custos.user.profile.persistance.model.UserProfile;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface UserRepository extends JpaRepository<UserProfile, String> {
+
+    public List<UserProfile> findByTenantId(long tenantId);
+
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/service/UserProfileService.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/service/UserProfileService.java
new file mode 100644
index 0000000..16490e3
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/service/UserProfileService.java
@@ -0,0 +1,1452 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.service;
+
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.user.profile.mapper.AttributeUpdateMetadataMapper;
+import org.apache.custos.user.profile.mapper.GroupMapper;
+import org.apache.custos.user.profile.mapper.StatusUpdateMetadataMapper;
+import org.apache.custos.user.profile.mapper.UserProfileMapper;
+import org.apache.custos.user.profile.persistance.model.UserProfile;
+import org.apache.custos.user.profile.persistance.model.*;
+import org.apache.custos.user.profile.persistance.repository.*;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+@GRpcService
+public class UserProfileService extends UserProfileServiceGrpc.UserProfileServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserProfileService.class);
+
+    @Autowired
+    private UserRepository repository;
+
+    @Autowired
+    private StatusUpdateMetadataRepository statusUpdaterRepository;
+
+    @Autowired
+    private AttributeUpdateMetadataRepository attributeUpdateMetadataRepository;
+
+    @Autowired
+    private UserAttributeRepository userAttributeRepository;
+
+    @Autowired
+    private RoleRepository roleRepository;
+
+    @Autowired
+    private GroupRepository groupRepository;
+
+    @Autowired
+    private GroupRoleRepository groupRoleRepository;
+
+    @Autowired
+    private GroupAttributeRepository groupAttributeRepository;
+
+    @Autowired
+    private GroupMembershipRepository groupMembershipRepository;
+
+    @Autowired
+    private GroupToGroupMembershipRepository groupToGroupMembershipRepository;
+
+    @Autowired
+    private GroupMembershipTypeRepository groupMembershipTypeRepository;
+
+
+    @Override
+    public void createUserProfile(UserProfileRequest request, StreamObserver<org.apache.custos.user.profile.service.UserProfile> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createUserProfile for " + request.getProfile().getUsername() + "at " + request.getTenantId());
+
+            String userId = request.getProfile().getUsername() + "@" + request.getTenantId();
+
+            Optional<UserProfile> op = repository.findById(userId);
+
+            if (op.isEmpty()) {
+
+                UserProfile entity = UserProfileMapper.createUserProfileEntityFromUserProfile(request.getProfile());
+                entity.setId(userId);
+                entity.setTenantId(request.getTenantId());
+                repository.save(entity);
+            }
+
+            responseObserver.onNext(request.getProfile());
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while creating user profile for " + request.getProfile().getUsername() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void updateUserProfile(UserProfileRequest request, StreamObserver<org.apache.custos.user.profile.service.UserProfile> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateUserProfile for " + request.getProfile().getUsername() + "at " + request.getTenantId());
+
+            String userId = request.getProfile().getUsername() + "@" + request.getTenantId();
+
+            Optional<UserProfile> exEntity = repository.findById(userId);
+
+
+            if (exEntity.isPresent()) {
+
+
+                UserProfile entity = UserProfileMapper.createUserProfileEntityFromUserProfile(request.getProfile());
+
+
+                Set<AttributeUpdateMetadata> metadata = AttributeUpdateMetadataMapper.
+                        createAttributeUpdateMetadataEntity(exEntity.get(), entity, request.getPerformedBy());
+
+
+                entity.setAttributeUpdateMetadata(metadata);
+                entity.setId(userId);
+                entity.setTenantId(request.getTenantId());
+                entity.setCreatedAt(exEntity.get().getCreatedAt());
+
+                UserProfile exProfile = exEntity.get();
+
+                if (exProfile.getUserAttribute() != null) {
+                    exProfile.getUserAttribute().forEach(atr -> {
+                        userAttributeRepository.delete(atr);
+
+                    });
+                }
+
+                if (exProfile.getUserRole() != null) {
+                    exProfile.getUserRole().forEach(role -> {
+                        roleRepository.delete(role);
+                    });
+                }
+
+                repository.save(entity);
+
+                responseObserver.onNext(request.getProfile());
+                responseObserver.onCompleted();
+            } else {
+                String msg = "Cannot find a user profile for " + userId;
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while updating user profile for " + request.getProfile().getUsername() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getUserProfile(UserProfileRequest request, StreamObserver<org.apache.custos.user.profile.service.UserProfile> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getUserProfile for " + request.getProfile().getUsername() + "at " + request.getTenantId());
+
+            String userId = request.getProfile().getUsername() + "@" + request.getTenantId();
+
+            Optional<UserProfile> entity = repository.findById(userId);
+
+            if (entity.isPresent()) {
+                UserProfile profileEntity = entity.get();
+                org.apache.custos.user.profile.service.UserProfile profile = UserProfileMapper.createUserProfileFromUserProfileEntity(profileEntity, null);
+
+                responseObserver.onNext(profile);
+                responseObserver.onCompleted();
+
+            } else {
+
+                responseObserver.onNext(null);
+                responseObserver.onCompleted();
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching user profile for " + request.getProfile().getUsername() + "at " + request.getTenantId();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteUserProfile(UserProfileRequest request, StreamObserver<org.apache.custos.user.profile.service.UserProfile> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteUserProfile for " + request.getProfile().getUsername() + "at " + request.getTenantId());
+            long tenantId = request.getTenantId();
+
+            String username = request.getProfile().getUsername();
+
+            String userId = username + "@" + tenantId;
+
+            Optional<UserProfile> profileEntity = repository.findById(userId);
+
+            if (profileEntity.isPresent()) {
+                UserProfile entity = profileEntity.get();
+
+                org.apache.custos.user.profile.service.UserProfile prof = UserProfileMapper.createUserProfileFromUserProfileEntity(entity, null);
+
+                repository.delete(profileEntity.get());
+                responseObserver.onNext(prof);
+                responseObserver.onCompleted();
+            } else {
+                responseObserver.onError(Status.NOT_FOUND.withDescription("User profile not found")
+                        .asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting user profile for " + request.getProfile().getUsername() + "at " + request.getTenantId();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAllUserProfilesInTenant(UserProfileRequest request,
+                                           StreamObserver<GetAllUserProfilesResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllUserProfilesInTenant for " + request.getTenantId());
+            long tenantId = request.getTenantId();
+
+            List<UserProfile> profileList = repository.findByTenantId(tenantId);
+
+            List<org.apache.custos.user.profile.service.UserProfile> userProfileList = new ArrayList<>();
+
+            if (profileList != null && profileList.size() > 0) {
+                for (UserProfile entity : profileList) {
+                    org.apache.custos.user.profile.service.UserProfile prof = UserProfileMapper.createUserProfileFromUserProfileEntity(entity, null);
+                    userProfileList.add(prof);
+                }
+            }
+
+            GetAllUserProfilesResponse response = GetAllUserProfilesResponse
+                    .newBuilder()
+                    .addAllProfiles(userProfileList)
+                    .build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching  user profile for tenant " + request.getTenantId();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+
+    @Override
+    public void findUserProfilesByAttributes(UserProfileRequest request, StreamObserver<GetAllUserProfilesResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to findUserProfilesByAttributes at " + request.getTenantId());
+
+
+            List<UserAttribute> attributeList = request.getProfile().getAttributesList();
+
+            List<UserProfile> selectedProfiles = new ArrayList<>();
+            List<org.apache.custos.user.profile.service.UserProfile> userProfileList = new ArrayList<>();
+            attributeList.forEach(atr -> {
+
+                List<String> values = atr.getValueList();
+                values.forEach(val -> {
+                    List<UserProfile>
+                            userAttributes = userAttributeRepository.findFilteredUserProfiles(atr.getKey(), val);
+                    if (userAttributes == null || userAttributes.isEmpty()) {
+                        GetAllUserProfilesResponse response = GetAllUserProfilesResponse
+                                .newBuilder()
+                                .build();
+                        responseObserver.onNext(response);
+                        responseObserver.onCompleted();
+                        return;
+                    }
+                    if (selectedProfiles.isEmpty()) {
+                        selectedProfiles.addAll(userAttributes);
+                    } else {
+                        List<UserProfile> profiles = userAttributes.stream().filter(newProf -> {
+                            AtomicBoolean matched = new AtomicBoolean(false);
+                            selectedProfiles.forEach(selectedProfile -> {
+                                if (selectedProfile.getId().equals(newProf.getId())) {
+                                    matched.set(true);
+                                }
+                            });
+                            return matched.get();
+                        }).collect(Collectors.toList());
+                        selectedProfiles.clear();
+                        selectedProfiles.addAll(profiles);
+                    }
+                });
+            });
+
+            if (!selectedProfiles.isEmpty()) {
+
+                selectedProfiles.forEach(userProfile -> {
+                    org.apache.custos.user.profile.service.UserProfile prof =
+                            UserProfileMapper.createUserProfileFromUserProfileEntity(userProfile, null);
+                    userProfileList.add(prof);
+
+                });
+                GetAllUserProfilesResponse response = GetAllUserProfilesResponse
+                        .newBuilder()
+                        .addAllProfiles(userProfileList)
+                        .build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+
+
+            } else {
+                GetAllUserProfilesResponse response = GetAllUserProfilesResponse
+                        .newBuilder()
+                        .build();
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching user profile for " + request.getProfile().getUsername() + "at " + request.getTenantId();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getUserProfileAuditTrails(GetUpdateAuditTrailRequest request,
+                                          StreamObserver<GetUpdateAuditTrailResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getUserProfileAuditTrails for " + request.getUsername() + "at " + request.getTenantId());
+
+            String username = request.getUsername();
+
+            long tenantId = request.getTenantId();
+
+            String userId = username + "@" + tenantId;
+
+            List<StatusUpdateMetadata> statusUpdateMetadata = statusUpdaterRepository.findAllByUserProfileId(userId);
+
+            List<AttributeUpdateMetadata> attributeUpdateMetadata = attributeUpdateMetadataRepository.findAllByUserProfileId(userId);
+
+            List<UserProfileStatusUpdateMetadata> userProfileStatusUpdateMetadata = new ArrayList<>();
+            List<UserProfileAttributeUpdateMetadata> userProfileAttributeUpdateMetadata = new ArrayList<>();
+
+            if (statusUpdateMetadata != null && statusUpdateMetadata.size() > 0) {
+
+                for (StatusUpdateMetadata metadata : statusUpdateMetadata) {
+
+                    UserProfileStatusUpdateMetadata met = StatusUpdateMetadataMapper.createUserProfileStatusMetadataFrom(metadata);
+                    userProfileStatusUpdateMetadata.add(met);
+                }
+
+            }
+
+
+            if (attributeUpdateMetadata != null && attributeUpdateMetadata.size() > 0) {
+
+                for (AttributeUpdateMetadata metadata : attributeUpdateMetadata) {
+
+                    UserProfileAttributeUpdateMetadata met = AttributeUpdateMetadataMapper.createAttributeUpdateMetadataFromEntity(metadata);
+                    userProfileAttributeUpdateMetadata.add(met);
+                }
+
+            }
+
+            GetUpdateAuditTrailResponse response = GetUpdateAuditTrailResponse
+                    .newBuilder()
+                    .addAllAttributeAudit(userProfileAttributeUpdateMetadata)
+                    .addAllStatusAudit(userProfileStatusUpdateMetadata)
+                    .build();
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching  audit trials " + request.getUsername() + "at " + request.getTenantId();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+
+    @Override
+    public void createGroup(GroupRequest request, StreamObserver<Group> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createGroup from tenant" + request.getTenantId());
+
+            String groupId = request.getGroup().getId();
+            long tenantId = request.getTenantId();
+
+            String effectiveId = groupId + "@" + tenantId;
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> op = groupRepository.findById(effectiveId);
+
+            String ownerId = request.getGroup().getOwnerId() + "@" + tenantId;
+
+            Optional<UserProfile> userProfile = repository.findById(ownerId);
+
+            if (userProfile.isEmpty()) {
+                String msg = "Error occurred while creating  Group for " + request.getTenantId()
+                        + " reason : Owner  not found";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            org.apache.custos.user.profile.persistance.model.Group savedGroup = null;
+            if (op.isEmpty()) {
+
+                org.apache.custos.user.profile.persistance.model.Group entity =
+                        GroupMapper.createGroupEntity(request.getGroup(), request.getTenantId());
+
+                String parentId = entity.getParentId();
+                if (parentId != null && !parentId.trim().equals("")) {
+
+                    Optional<org.apache.custos.user.profile.persistance.model.Group> parent = groupRepository.findById(parentId);
+
+                    if (parent.isEmpty()) {
+                        String msg = "Error occurred while creating  Group for " + request.getTenantId()
+                                + " reason : Parent group not found";
+                        LOGGER.error(msg);
+                        responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                        return;
+                    }
+
+                    entity = GroupMapper.setParentGroupMembership(parent.get(), entity);
+                }
+
+                savedGroup = groupRepository.save(entity);
+            }
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> exOP =
+                    groupRepository.findById(effectiveId);
+
+            if (exOP.isPresent()) {
+                String type = DefaultGroupMembershipTypes.OWNER.name();
+
+                Optional<UserGroupMembershipType> groupMembershipType = groupMembershipTypeRepository.findById(type);
+                UserGroupMembershipType exist = null;
+
+                if (groupMembershipType.isEmpty()) {
+                    exist = new UserGroupMembershipType();
+                    exist.setId(type);
+                    groupMembershipTypeRepository.save(exist);
+                }
+
+                exist = groupMembershipType.get();
+
+
+                UserGroupMembership userGroupMembership = new
+                        UserGroupMembership();
+                userGroupMembership.setGroup(savedGroup);
+                userGroupMembership.setUserProfile(userProfile.get());
+                userGroupMembership.setTenantId(tenantId);
+
+                userGroupMembership.setUserGroupMembershipType(exist);
+                groupMembershipRepository.save(userGroupMembership);
+
+                Group exGroup = GroupMapper.createGroup(exOP.get(), ownerId);
+                responseObserver.onNext(exGroup);
+                responseObserver.onCompleted();
+            } else {
+
+                String msg = "Error occurred while creating Group for " + request.getTenantId()
+                        + " reason : DB error";
+                LOGGER.error(msg);
+
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while creating Group for " + request.getTenantId() +
+                    " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void updateGroup(GroupRequest request, StreamObserver<Group> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateGroup for group with id  " + request.getGroup().getId() +
+                    "at tenant " + request.getTenantId());
+
+            String groupId = request.getGroup().getId();
+
+            long tenantId = request.getTenantId();
+
+            String effectiveId = groupId + "@" + tenantId;
+
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> exEntity =
+                    groupRepository.findById(effectiveId);
+
+
+            if (exEntity.isPresent()) {
+
+
+                org.apache.custos.user.profile.persistance.model.Group entity = GroupMapper.
+                        createGroupEntity(request.getGroup(), request.getTenantId());
+
+
+                entity.setCreatedAt(exEntity.get().getCreatedAt());
+
+                org.apache.custos.user.profile.persistance.model.Group exGroup = exEntity.get();
+
+                if (exGroup.getGroupAttribute() != null) {
+                    exGroup.getGroupAttribute().forEach(atr -> {
+                        groupAttributeRepository.delete(atr);
+
+                    });
+                }
+
+                if (exGroup.getGroupRole() != null) {
+                    exGroup.getGroupRole().forEach(role -> {
+                        groupRoleRepository.delete(role);
+                    });
+                }
+
+                groupRepository.save(entity);
+
+                Optional<org.apache.custos.user.profile.persistance.model.Group> exOP =
+                        groupRepository.findById(effectiveId);
+
+
+                if (exOP.isPresent()) {
+                    List<UserGroupMembership> userGroupMemberships = groupMembershipRepository.findAllByGroupId(effectiveId);
+
+                    String ownerId = null;
+                    for (UserGroupMembership userGroupMembership : userGroupMemberships) {
+                        if (userGroupMembership.getUserGroupMembershipType().getId().equals(DefaultGroupMembershipTypes.OWNER.name())) {
+                            ownerId = userGroupMembership.getUserProfile().getUsername();
+                        }
+                    }
+
+                    Group exNewGroup = GroupMapper.createGroup(exOP.get(), ownerId);
+                    responseObserver.onNext(exNewGroup);
+                    responseObserver.onCompleted();
+                } else {
+
+                    String msg = "Error occurred while updating group  " + request.getTenantId()
+                            + " reason : DB error";
+                    LOGGER.error(msg);
+
+                    responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                }
+
+            } else {
+                String msg = "Cannot find a group for " + groupId;
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while updating group " + request.getGroup().getId() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void deleteGroup(GroupRequest request, StreamObserver<Group> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteGroup for " + request.getGroup().getId() + "at " + request.getTenantId());
+
+            String userId = request.getGroup().getId();
+            long tenantId = request.getTenantId();
+
+            String effectiveId = userId + "@" + tenantId;
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> op = groupRepository.findById(effectiveId);
+
+            if (op.isPresent()) {
+                org.apache.custos.user.profile.persistance.model.Group entity = op.get();
+
+                List<UserGroupMembership> userGroupMemberships = groupMembershipRepository.findAllByGroupId(effectiveId);
+
+                String ownerId = null;
+                for (UserGroupMembership userGroupMembership : userGroupMemberships) {
+                    if (userGroupMembership.getUserGroupMembershipType().getId().equals(DefaultGroupMembershipTypes.OWNER.name())) {
+                        ownerId = userGroupMembership.getUserProfile().getUsername();
+                    }
+                }
+
+
+                Group prof = GroupMapper.createGroup(entity, ownerId);
+
+                groupRepository.delete(op.get());
+
+                List<org.apache.custos.user.profile.persistance.model.Group> groupList = groupRepository.findByParentId(entity.getId());
+
+                if (groupList != null && !groupList.isEmpty()) {
+                    for (org.apache.custos.user.profile.persistance.model.Group group : groupList) {
+                        groupRepository.delete(group);
+                    }
+
+                }
+
+                responseObserver.onNext(prof);
+                responseObserver.onCompleted();
+            } else {
+                responseObserver.onError(Status.NOT_FOUND.withDescription("Group not found")
+                        .asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while creating group for " + request.getGroup() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getGroup(GroupRequest request, StreamObserver<Group> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getGroup for group " + request.getGroup().getId() + "at " + request.getTenantId());
+
+            String userId = request.getGroup().getId();
+
+            long tenantId = request.getTenantId();
+
+            String effectiveId = userId + "@" + tenantId;
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> op = groupRepository.findById(effectiveId);
+
+            if (op.isPresent()) {
+
+                List<UserGroupMembership> userGroupMemberships = groupMembershipRepository.findAllByGroupId(effectiveId);
+
+                String ownerId = null;
+                for (UserGroupMembership userGroupMembership : userGroupMemberships) {
+                    if (userGroupMembership.getUserGroupMembershipType().getId().equals(DefaultGroupMembershipTypes.OWNER.name())) {
+                        ownerId = userGroupMembership.getUserProfile().getUsername();
+                    }
+                }
+                Group entity = GroupMapper.createGroup(op.get(), ownerId);
+
+                responseObserver.onNext(entity);
+                responseObserver.onCompleted();
+
+            } else {
+                responseObserver.onNext(null);
+                responseObserver.onCompleted();
+
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching group " + request.getGroup().getId() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void getAllGroups(GroupRequest request, StreamObserver<GetAllGroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllGroups for " + request.getTenantId());
+
+            List<org.apache.custos.user.profile.persistance.model.Group> groups = groupRepository.findAll();
+
+            List<Group> groupList = new ArrayList<>();
+
+            if (groups != null && groups.isEmpty()) {
+                for (org.apache.custos.user.profile.persistance.model.Group group : groups) {
+
+                    List<UserGroupMembership> userGroupMemberships = groupMembershipRepository.findAllByGroupId(group.getId());
+
+                    String ownerId = null;
+                    for (UserGroupMembership userGroupMembership : userGroupMemberships) {
+                        if (userGroupMembership.getUserGroupMembershipType().getId().equals(DefaultGroupMembershipTypes.OWNER.name())) {
+                            ownerId = userGroupMembership.getUserProfile().getUsername();
+                        }
+                    }
+                    Group gr = GroupMapper.createGroup(group, ownerId);
+
+                    groupList.add(gr);
+                }
+            }
+            GetAllGroupsResponse response = GetAllGroupsResponse.newBuilder().addAllGroups(groupList).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching groups for " + request.getTenantId() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addUserToGroup(GroupMembership request,
+                               StreamObserver<org.apache.custos.user.profile.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addUserToGroup for " + request.getTenantId());
+
+            String group_id = request.getGroupId();
+            String username = request.getUsername();
+            long tenantId = request.getTenantId();
+            String userId = username + "@" + tenantId;
+
+            String effectiveGroupId = group_id + "@" + tenantId;
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> group = groupRepository.findById(effectiveGroupId);
+            Optional<UserProfile> userProfile = repository.findById(userId);
+
+            if (group.isPresent() && userProfile.isPresent()) {
+
+                List<UserGroupMembership> memberships =
+                        groupMembershipRepository.findAllByGroupIdAndUserProfileId(effectiveGroupId, userId);
+
+                if (memberships == null || memberships.isEmpty()) {
+
+
+                    String type = request.getType();
+                    if (type == null || type.trim().equals("")) {
+                        type = DefaultGroupMembershipTypes.MEMBER.name();
+                    } else {
+                        type = type.toUpperCase();
+                    }
+
+                    Optional<UserGroupMembershipType> groupMembershipType = groupMembershipTypeRepository.findById(type);
+                    UserGroupMembershipType exist = null;
+
+                    if (groupMembershipType.isEmpty()) {
+                        exist = new UserGroupMembershipType();
+                        exist.setId(type);
+                        groupMembershipTypeRepository.save(exist);
+                    }
+
+                    exist = groupMembershipType.get();
+
+                    UserGroupMembership userGroupMembership = new
+                            UserGroupMembership();
+                    userGroupMembership.setGroup(group.get());
+                    userGroupMembership.setUserProfile(userProfile.get());
+                    userGroupMembership.setTenantId(tenantId);
+
+                    userGroupMembership.setUserGroupMembershipType(exist);
+                    groupMembershipRepository.save(userGroupMembership);
+                }
+
+                org.apache.custos.user.profile.service.Status status = org.apache.custos.user.profile.service.Status
+                        .newBuilder()
+                        .setStatus(true).build();
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+            } else {
+                String msg = "Group or user not available";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching groups for " + request.getTenantId() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeUserFromGroup(GroupMembership request,
+                                    StreamObserver<org.apache.custos.user.profile.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to removeUserFromGroup for " + request.getTenantId());
+
+            String group_id = request.getGroupId();
+            String username = request.getUsername();
+            long tenantId = request.getTenantId();
+            String userId = username + "@" + tenantId;
+
+            String effectiveGroupId = group_id + "@" + tenantId;
+
+            List<UserGroupMembership> memberships =
+                    groupMembershipRepository.findAllByGroupIdAndUserProfileId(effectiveGroupId, userId);
+
+            if (memberships != null && !memberships.isEmpty()) {
+
+                memberships.forEach(membership -> {
+                    groupMembershipRepository.delete(membership);
+                });
+            }
+            org.apache.custos.user.profile.service.Status status = org.apache.custos.user.profile.service.Status
+                    .newBuilder()
+                    .setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching groups for " + request.getTenantId() + "at "
+                    + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void addChildGroupToParentGroup(GroupToGroupMembership request,
+                                           StreamObserver<org.apache.custos.user.profile.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addChildGroupToParentGroup for " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+
+            String childId = request.getChildId();
+
+            String parentId = request.getParentId();
+
+            String effectiveChildId = childId + "@" + tenantId;
+            String effectiveParentId = parentId + "@" + tenantId;
+
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> childEntity = groupRepository.
+                    findById(effectiveChildId);
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> parentEntity = groupRepository.
+                    findById(effectiveParentId);
+
+            if (childEntity.isEmpty() || parentEntity.isEmpty()) {
+                String msg = "Child or parent group not available";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            }
+
+            List<org.apache.custos.user.profile.persistance.model.GroupToGroupMembership> groupToGroupMemberships =
+                    groupToGroupMembershipRepository.findByChildIdAndParentId(effectiveChildId, effectiveParentId);
+            if (groupToGroupMemberships == null || groupToGroupMemberships.isEmpty()) {
+
+                org.apache.custos.user.profile.persistance.model.GroupToGroupMembership membership =
+                        GroupMapper.groupToGroupMembership(childEntity.get(), parentEntity.get());
+
+                org.apache.custos.user.profile.persistance.model.GroupToGroupMembership saved =
+                        groupToGroupMembershipRepository.save(membership);
+
+                if (saved != null && saved.getId() != null) {
+                    org.apache.custos.user.profile.service.Status status =
+                            org.apache.custos.user.profile.service.Status.newBuilder().setStatus(true).build();
+                    responseObserver.onNext(status);
+                    responseObserver.onCompleted();
+                } else {
+                    String msg = "Group membership creation failed";
+                    LOGGER.error(msg);
+                    responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                }
+            } else {
+                org.apache.custos.user.profile.service.Status status =
+                        org.apache.custos.user.profile.service.Status.newBuilder().setStatus(true).build();
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while adding child group to parent group for " + request.getTenantId() +
+                    " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeChildGroupFromParentGroup(GroupToGroupMembership request,
+                                                StreamObserver<org.apache.custos.user.profile.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to removeChildGroupFromParentGroup for " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+
+            String childId = request.getChildId();
+
+            String parentId = request.getParentId();
+
+            String effectiveChildId = childId + "@" + tenantId;
+            String effectiveParentId = parentId + "@" + tenantId;
+
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> childEntity = groupRepository.
+                    findById(effectiveChildId);
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> parentEntity = groupRepository.
+                    findById(effectiveParentId);
+
+            if (childEntity.isEmpty() || parentEntity.isEmpty()) {
+                String msg = "Child or parent group not available";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            }
+
+
+            List<org.apache.custos.user.profile.persistance.model.GroupToGroupMembership> groupToGroupMemberships =
+                    groupToGroupMembershipRepository.findByChildIdAndParentId(effectiveChildId, effectiveParentId);
+
+            if (groupToGroupMemberships != null && !groupToGroupMemberships.isEmpty()) {
+                groupToGroupMembershipRepository.delete(groupToGroupMemberships.get(0));
+
+            }
+
+            org.apache.custos.user.profile.service.Status status =
+                    org.apache.custos.user.profile.service.Status.newBuilder().setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while remove child group from parent group for " + request.getTenantId() +
+                    " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAllGroupsOfUser(UserProfileRequest request, StreamObserver<GetAllGroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllGroupsOfUser for " + request.getTenantId());
+
+            long tenantId = request.getTenantId();
+            String username = request.getProfile().getUsername();
+
+            String userId = username + "@" + tenantId;
+
+            List<UserGroupMembership> userGroupMemberships = groupMembershipRepository.findAllByUserProfileId(userId);
+
+            List<org.apache.custos.user.profile.persistance.model.Group> groups = new ArrayList<>();
+
+            if (userGroupMemberships != null && !userGroupMemberships.isEmpty()) {
+
+                userGroupMemberships.forEach(userGroupMembership -> {
+
+                    AtomicBoolean toBeAdded = new AtomicBoolean(true);
+                    groups.forEach(le -> {
+                        if (le.getId().equals(userGroupMembership.getGroup().getId())) {
+                            toBeAdded.set(false);
+                        }
+                    });
+
+                    if (toBeAdded.get()) {
+                        groups.add(userGroupMembership.getGroup());
+                    }
+                });
+
+            }
+
+            Map<String, org.apache.custos.user.profile.persistance.model.Group> groupMap =
+                    getAllUniqueGroups(groups, null);
+
+
+            List<Group> groupList = new ArrayList<>();
+
+
+            groupMap.keySet().forEach(gr -> {
+
+                List<UserGroupMembership> memberships = groupMembershipRepository.findAllByGroupId(gr);
+
+                String ownerId = null;
+                for (UserGroupMembership userGroupMembership : memberships) {
+                    if (userGroupMembership.getUserGroupMembershipType().getId().equals(DefaultGroupMembershipTypes.OWNER.name())) {
+                        ownerId = userGroupMembership.getUserProfile().getUsername();
+                        break;
+                    }
+                }
+                groupList.add(GroupMapper.createGroup(groupMap.get(gr), ownerId));
+            });
+
+
+            GetAllGroupsResponse getAllGroupsResponse =
+                    GetAllGroupsResponse.newBuilder().addAllGroups(groupList).build();
+            responseObserver.onNext(getAllGroupsResponse);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching user groups of user " + request.getProfile().getUsername() +
+                    " in tenant " + request.getTenantId() +
+                    " reason :" + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAllParentGroupsOfGroup(GroupRequest request, StreamObserver<GetAllGroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllParentGroupsOfGroup for " + request.getTenantId());
+
+            String groupId = request.getGroup().getId();
+            long tenantId = request.getTenantId();
+
+            String effectiveId = groupId + "@" + tenantId;
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> groups = groupRepository.findById(effectiveId);
+
+            if (groups.isEmpty()) {
+                GetAllGroupsResponse getAllGroupsResponse = GetAllGroupsResponse.newBuilder().build();
+                responseObserver.onNext(getAllGroupsResponse);
+                responseObserver.onCompleted();
+                return;
+            } else {
+                List<org.apache.custos.user.profile.persistance.model.Group> groupList = new ArrayList<>();
+                groupList.add(groups.get());
+
+                Map<String, org.apache.custos.user.profile.persistance.model.Group> groupMap =
+                        getAllUniqueGroups(groupList, null);
+
+                List<Group> serviceGroupList = new ArrayList<>();
+
+
+                groupMap.keySet().forEach(gr -> {
+
+                    List<UserGroupMembership> userGroupMemberships = groupMembershipRepository.findAllByGroupId(effectiveId);
+
+                    String ownerId = null;
+                    for (UserGroupMembership userGroupMembership : userGroupMemberships) {
+                        if (userGroupMembership.getUserGroupMembershipType().getId().equals(DefaultGroupMembershipTypes.OWNER.name())) {
+                            ownerId = userGroupMembership.getUserProfile().getUsername();
+                        }
+                    }
+
+                    serviceGroupList.add(GroupMapper.createGroup(groupMap.get(gr), ownerId));
+                });
+
+
+                GetAllGroupsResponse getAllGroupsResponse =
+                        GetAllGroupsResponse.newBuilder().addAllGroups(serviceGroupList).build();
+                responseObserver.onNext(getAllGroupsResponse);
+                responseObserver.onCompleted();
+
+
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching all parent groups for group " + request.getGroup().getId() +
+                    "in tenant " + request.getTenantId() +
+                    " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void addUserGroupMembershipType(UserGroupMembershipTypeRequest request,
+                                           StreamObserver<org.apache.custos.user.profile.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addUserGroupMembershipType of type  " + request.getType());
+
+            String type = request.getType().toUpperCase();
+
+            Optional<UserGroupMembershipType> userGroupMembershipType = groupMembershipTypeRepository.findById(type);
+
+            if (userGroupMembershipType.isEmpty()) {
+
+                UserGroupMembershipType userGroupType = new UserGroupMembershipType();
+                userGroupType.setId(type);
+                groupMembershipTypeRepository.save(userGroupType);
+
+            }
+
+            org.apache.custos.user.profile.service.Status status = org.apache.custos.user.profile.service.Status
+                    .newBuilder()
+                    .setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while saving group membership type" + request.getType();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeUserGroupMembershipType(UserGroupMembershipTypeRequest request,
+                                              StreamObserver<org.apache.custos.user.profile.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to removeUserGroupMembershipType of type " + request.getType());
+
+            String type = request.getType().toUpperCase();
+
+            Optional<UserGroupMembershipType> userGroupMembershipType = groupMembershipTypeRepository.findById(type);
+
+            if (userGroupMembershipType.isPresent()) {
+
+                groupMembershipTypeRepository.delete(userGroupMembershipType.get());
+            }
+
+            org.apache.custos.user.profile.service.Status status = org.apache.custos.user.profile.service.Status
+                    .newBuilder()
+                    .setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting removeUserGroupMembershipType of type  " + request.getType();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAllChildUsers(GroupRequest request, StreamObserver<GetAllUserProfilesResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllChildUsers in tenant " + request.getTenantId() +
+                    " for group with Id " + request.getGroup().getId());
+
+            long tenantId = request.getTenantId();
+            String username = request.getGroup().getId();
+
+            String effectiveId = username + "@" + tenantId;
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> groupOptional = groupRepository.findById(effectiveId);
+
+            if (groupOptional.isEmpty()) {
+                String msg = "group not found";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            List<UserGroupMembership> memberships = groupMembershipRepository.findAllByGroupId(effectiveId);
+
+            List<org.apache.custos.user.profile.service.UserProfile> userProfileList = new ArrayList<>();
+
+            List<UserGroupMembership> selectedProfiles = new ArrayList<>();
+
+
+            if (memberships != null && !memberships.isEmpty()) {
+
+                memberships.forEach(mem -> {
+
+                    AtomicBoolean addToList = new AtomicBoolean(true);
+
+                    selectedProfiles.forEach(ex -> {
+                        if (ex.getId().equals(mem.getUserProfile().getId())) {
+                            addToList.set(false);
+                        }
+                    });
+
+                    if (addToList.get()) {
+                        selectedProfiles.add(mem);
+                    }
+                });
+            }
+
+            if (!selectedProfiles.isEmpty()) {
+                selectedProfiles.forEach(gr -> {
+                    userProfileList.add(UserProfileMapper.createUserProfileFromUserProfileEntity(gr.getUserProfile(),
+                            gr.getUserGroupMembershipType().getId()));
+                });
+            }
+
+            GetAllUserProfilesResponse getAllUserProfilesResponse = GetAllUserProfilesResponse
+                    .newBuilder()
+                    .addAllProfiles(userProfileList)
+                    .build();
+            responseObserver.onNext(getAllUserProfilesResponse);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching all child users in tenant " + request.getTenantId() +
+                    " for group with Id " + request.getGroup().getId();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAllChildGroups(GroupRequest request, StreamObserver<GetAllGroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllChildGroups in tenant " + request.getTenantId() +
+                    " for group with Id " + request.getGroup().getId());
+
+            long tenantId = request.getTenantId();
+            String groupId = request.getGroup().getId();
+
+            String effectiveParentId = groupId + "@" + tenantId;
+
+
+            Optional<org.apache.custos.user.profile.persistance.model.Group> groupOptional = groupRepository.findById(effectiveParentId);
+
+            if (groupOptional.isEmpty()) {
+                String msg = "group not found";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+
+            List<org.apache.custos.user.profile.persistance.model.GroupToGroupMembership> memberships =
+                    groupToGroupMembershipRepository.findAllByParentId(effectiveParentId);
+
+            List<org.apache.custos.user.profile.service.Group> groupList = new ArrayList<>();
+
+            HashMap<String, org.apache.custos.user.profile.persistance.model.Group> selectedGroupMap = new HashMap<>();
+
+
+            if (memberships != null && !memberships.isEmpty()) {
+
+                memberships.forEach(mem -> {
+                    selectedGroupMap.put(mem.getChild().getId(), mem.getChild());
+
+                });
+            }
+
+
+            selectedGroupMap.values().forEach(group -> {
+                List<UserGroupMembership> groupMemberships = groupMembershipRepository.
+                        findAllByGroupId(group.getId());
+                AtomicReference<String> ownerId = new AtomicReference<>();
+                groupMemberships.forEach(grm -> {
+                    if (grm.getUserGroupMembershipType().getId().equals(DefaultGroupMembershipTypes.OWNER.name())) {
+                        ownerId.set(grm.getUserProfile().getUsername());
+                    }
+                });
+
+                groupList.add(GroupMapper.createGroup(group, ownerId.get()));
+
+
+            });
+
+            GetAllGroupsResponse getAllUserProfilesResponse = GetAllGroupsResponse
+                    .newBuilder()
+                    .addAllGroups(groupList)
+                    .build();
+            responseObserver.onNext(getAllUserProfilesResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching all child groups in tenant " + request.getTenantId() +
+                    " for group with Id " + request.getGroup().getId();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void changeUserMembershipType(GroupMembership request,
+                                         StreamObserver<org.apache.custos.user.profile.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to changeUserMembershipType in   tenant"
+                    + request.getTenantId() + " with id " + request.getUsername() + " to " + request.getType());
+
+            long tenantId = request.getTenantId();
+            String username = request.getUsername();
+            String groupId = request.getGroupId();
+            String type = request.getType();
+
+
+            String userId = username + "@" + tenantId;
+            String effectiveGroupId = groupId + "@" + tenantId;
+
+
+            List<UserGroupMembership> userGroupMemberships =
+                    groupMembershipRepository.findAllByGroupIdAndUserProfileId(effectiveGroupId, userId);
+
+            if (userGroupMemberships == null || userGroupMemberships.isEmpty()) {
+                String msg = "group membership not found";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            UserGroupMembership groupMembership = userGroupMemberships.get(0);
+
+            UserGroupMembershipType groupMembershipType = groupMembership.getUserGroupMembershipType();
+            groupMembershipType.setId(type);
+
+            groupMembership.setUserGroupMembershipType(groupMembershipType);
+
+            groupMembershipRepository.save(groupMembership);
+
+            if (type.equals(DefaultGroupMembershipTypes.OWNER.name())) {
+
+                List<UserGroupMembership> memberships = groupMembershipRepository.findAllByGroupId(effectiveGroupId);
+
+                if (memberships != null && !memberships.isEmpty()) {
+
+                    for (UserGroupMembership membership : memberships) {
+
+                        if (membership.getUserGroupMembershipType().getId().equals(DefaultGroupMembershipTypes.OWNER.name())
+                                && !membership.getUserProfile().getUsername().equals(userId)) {
+
+                            groupMembershipRepository.delete(membership);
+
+                            UserGroupMembership userGroupMembership = new
+                                    UserGroupMembership();
+                            userGroupMembership.setGroup(membership.getGroup());
+                            userGroupMembership.setUserProfile(membership.getUserProfile());
+                            userGroupMembership.setTenantId(tenantId);
+
+                            Optional<UserGroupMembershipType> membershipType = groupMembershipTypeRepository.
+                                    findById(DefaultGroupMembershipTypes.MEMBER.name());
+                            userGroupMembership.setUserGroupMembershipType(membershipType.get());
+                            groupMembershipRepository.save(userGroupMembership);
+
+                        }
+                    }
+
+
+                }
+
+            }
+
+
+            org.apache.custos.user.profile.service.Status status = org.apache.custos.user.profile.service.Status
+                    .newBuilder()
+                    .setStatus(true).build();
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while changing membership type  in   tenant"
+                    + request.getTenantId() + " with id " + request.getUsername() + " to " + request.getType();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void hasAccess(GroupMembership request,
+                          StreamObserver<org.apache.custos.user.profile.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to check access  in   tenant"
+                    + request.getTenantId() + " with id " + request.getUsername() + " to " + request.getType());
+
+            long tenantId = request.getTenantId();
+            String username = request.getUsername();
+            String groupId = request.getGroupId();
+            String type = request.getType();
+
+
+            String userId = username + "@" + tenantId;
+            String effectiveGroupId = groupId + "@" + tenantId;
+
+
+            List<UserGroupMembership> userGroupMemberships = groupMembershipRepository.
+                    findAllByGroupIdAndUserProfileIdAndUserGroupMembershipTypeId(effectiveGroupId, userId, type);
+            org.apache.custos.user.profile.service.Status status = null;
+
+            if (userGroupMemberships == null || userGroupMemberships.isEmpty()) {
+                status = org.apache.custos.user.profile.service.Status
+                        .newBuilder()
+                        .setStatus(false).build();
+            } else {
+                status = org.apache.custos.user.profile.service.Status
+                        .newBuilder()
+                        .setStatus(true).build();
+            }
+
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while checking access to   in   tenant"
+                    + request.getTenantId() + " with id " + request.getUsername() + " to " + request.getType();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    public boolean initializeDBConfigs() {
+
+        for (DefaultGroupMembershipTypes type : DefaultGroupMembershipTypes.values()) {
+
+            Optional<UserGroupMembershipType> typeOptional = groupMembershipTypeRepository.
+                    findById(type.name().toUpperCase());
+
+            if (typeOptional.isEmpty()) {
+                UserGroupMembershipType membershipType = new UserGroupMembershipType();
+                membershipType.setId(type.name().toUpperCase());
+                groupMembershipTypeRepository.save(membershipType);
+            }
+        }
+        return true;
+
+    }
+
+    private Map<String, org.apache.custos.user.profile.persistance.model.Group>
+    getAllUniqueGroups(List<org.apache.custos.user.profile.persistance.model.Group> leaveGroups,
+                       Map<String, org.apache.custos.user.profile.persistance.model.Group> allParentGroups) {
+
+        if (allParentGroups == null) {
+            allParentGroups = new HashMap<>();
+
+        }
+
+        if (leaveGroups != null && !leaveGroups.isEmpty()) {
+
+            for (org.apache.custos.user.profile.persistance.model.Group gr : leaveGroups) {
+                List<org.apache.custos.user.profile.persistance.model.GroupToGroupMembership> memberships
+                        = groupToGroupMembershipRepository.findAllByChildId(gr.getId());
+                List<org.apache.custos.user.profile.persistance.model.Group> leaves = new ArrayList<>();
+                allParentGroups.put(gr.getId(), gr);
+
+                if (memberships != null && !memberships.isEmpty()) {
+                    memberships.forEach(mem -> {
+                        AtomicBoolean toBeAdded = new AtomicBoolean(true);
+                        leaves.forEach(le -> {
+                            if (le.getId().equals(mem.getParent().getId())) {
+                                toBeAdded.set(false);
+                            }
+                        });
+
+                        if (toBeAdded.get()) {
+                            leaves.add(mem.getParent());
+                        }
+                    });
+
+                    getAllUniqueGroups(leaves, allParentGroups);
+
+                }
+
+            }
+
+
+        }
+
+        return allParentGroups;
+
+    }
+
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/utils/Constants.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/utils/Constants.java
new file mode 100644
index 0000000..7a7a877
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/utils/Constants.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.utils;
+
+public final class Constants {
+    public static final String ROLE_TYPE_REALM = "realm";
+    public static final  String ROLE_TYPE_CLIENT = "client";
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/validators/InputValidator.java b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/validators/InputValidator.java
new file mode 100644
index 0000000..bc702b3
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/java/org/apache/custos/user/profile/validators/InputValidator.java
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.profile.validators;
+
+import org.apache.custos.core.services.commons.Validator;
+import org.apache.custos.core.services.commons.exceptions.MissingParameterException;
+import org.apache.custos.user.profile.service.*;
+
+/**
+ * Validate inputs
+ */
+public class InputValidator implements Validator {
+    @Override
+    public void validate(String methodName, Object obj) {
+        switch (methodName) {
+            case "createUserProfile":
+            case "updateUserProfile":
+                validateUserProfile(obj, methodName);
+                break;
+            case "getUserProfile":
+            case "deleteUserProfile":
+            case "getUserProfileAuditTrails":
+                validateUsernameAndTenantId(obj, methodName);
+                break;
+            case "validateGetAllUserProfiles":
+                validateGetAllUserProfiles(obj, methodName);
+                break;
+
+            case "createGroup":
+                validateCreateGroup(obj, methodName);
+                break;
+            case "updateGroup":
+                validateUpdateGroup(obj, methodName);
+                break;
+            case "deleteGroup":
+                validateDeleteGroup(obj, methodName);
+                break;
+            case "getGroup":
+                validateFindGroup(obj, methodName);
+                break;
+            case "addUserToGroup":
+            case "removeUserFromGroup":
+            case "hasAccess":
+            case "changeUserMembershipType":
+                validateGroupMembership(obj, methodName);
+                break;
+
+            case "addChildGroupToParentGroup":
+            case "removeChildGroupFromParentGroup":
+                validateGroupToGroupMembership(obj, methodName);
+                break;
+
+            case "getAllGroupsOfUser":
+                validateGetAllGroupsOfUser(obj, methodName);
+                break;
+            case "getAllParentGroupsOfGroup":
+                validateGetAllParentGroupsOfGroup(obj, methodName);
+                break;
+            case "addUserGroupMembershipType":
+            case "removeUserGroupMembershipType":
+                validateUserGroupMembershipTypeRequest(obj, methodName);
+                break;
+            case "getAllChildUsers":
+            case "getAllChildGroups":
+                validateGetUserAndChildGroups(obj, methodName);
+                break;
+
+
+            default:
+
+        }
+    }
+
+
+    private boolean validateUserProfile(Object obj, String method) {
+        if (obj instanceof UserProfileRequest) {
+            UserProfileRequest profile = (UserProfileRequest) obj;
+
+            if (profile.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profile.getProfile() == null) {
+                throw new MissingParameterException("Profile should be valid ", null);
+            }
+            if (profile.getProfile().getUsername() == null || profile.getProfile().getUsername().equals("")) {
+                throw new MissingParameterException("username should not be null", null);
+            }
+
+            if ((profile.getProfile().getFirstName() == null || profile.getProfile().getFirstName().equals("")) &&
+                    !profile.getProfile().getType().equals(UserTypes.COMMUNITY) ) {
+                throw new MissingParameterException("firstName should not be null", null);
+            }
+            if ((profile.getProfile().getLastName() == null || profile.getProfile().getLastName().equals("")) &&
+                    !profile.getProfile().getType().equals(UserTypes.COMMUNITY)) {
+                throw new MissingParameterException("lastName should not be null", null);
+            }
+            if ((profile.getProfile().getEmail() == null || profile.getProfile().getEmail().equals("")) &&
+                    !profile.getProfile().getType().equals(UserTypes.COMMUNITY)) {
+                throw new MissingParameterException("emailAddress should not be null", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + method);
+        }
+        return true;
+    }
+
+
+    private boolean validateUsernameAndTenantId(Object obj, String method) {
+        if (method.equals("getUserProfile")) {
+            UserProfileRequest profileRequest = (UserProfileRequest) obj;
+            if (profileRequest.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profileRequest.getProfile() == null) {
+                throw new MissingParameterException("Profile should be valid ", null);
+            }
+            if (profileRequest.getProfile().getUsername() == null || profileRequest.getProfile().getUsername().equals("")) {
+                throw new MissingParameterException("username should not be null", null);
+            }
+        } else if (method.equals("deleteUserProfile")) {
+
+            UserProfileRequest profileRequest = (UserProfileRequest) obj;
+            if (profileRequest.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profileRequest.getProfile() == null) {
+                throw new MissingParameterException("Profile should be valid ", null);
+            }
+            if (profileRequest.getProfile().getUsername() == null || profileRequest.getProfile().getUsername().equals("")) {
+                throw new MissingParameterException("username should not be null", null);
+            }
+
+        } else if (method.equals("getUserProfileAuditTrails")) {
+
+            GetUpdateAuditTrailRequest profileRequest = (GetUpdateAuditTrailRequest) obj;
+            if (profileRequest.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profileRequest.getUsername() == null || profileRequest.getUsername().equals("")) {
+                throw new MissingParameterException("username should not be null", null);
+            }
+
+        }
+
+        return true;
+
+    }
+
+
+    private boolean validateCreateGroup(Object obj, String method) {
+        if (obj instanceof GroupRequest) {
+            GroupRequest profile = (GroupRequest) obj;
+
+            if (profile.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profile.getGroup() == null) {
+                throw new MissingParameterException("Group should be valid ", null);
+            }
+            if (profile.getGroup().getName() == null || profile.getGroup().getName().equals("")) {
+                throw new MissingParameterException("Name should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + method);
+        }
+        return true;
+
+    }
+
+    private boolean validateUpdateGroup(Object obj, String method) {
+        if (obj instanceof GroupRequest) {
+            GroupRequest profile = (GroupRequest) obj;
+
+            if (profile.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profile.getGroup() == null) {
+                throw new MissingParameterException("Group should be valid ", null);
+            }
+            if (profile.getGroup().getName() == null || profile.getGroup().getName().equals("")) {
+                throw new MissingParameterException("Name should not be null", null);
+            }
+
+            if (profile.getGroup().getId() == null || profile.getGroup().getId().equals("")) {
+                throw new MissingParameterException("Id should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + method);
+        }
+        return true;
+
+    }
+
+    private boolean validateDeleteGroup(Object obj, String method) {
+
+        if (obj instanceof GroupRequest) {
+            GroupRequest profile = (GroupRequest) obj;
+
+            if (profile.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profile.getGroup() == null) {
+                throw new MissingParameterException("Group should be valid ", null);
+            }
+            if (profile.getGroup().getId() == null) {
+                throw new MissingParameterException("Group Id be valid ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + method);
+        }
+        return true;
+    }
+
+    private boolean validateFindGroup(Object obj, String method) {
+        if (obj instanceof GroupRequest) {
+            GroupRequest profile = (GroupRequest) obj;
+
+            if (profile.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profile.getGroup() == null) {
+                throw new MissingParameterException("Group should be valid ", null);
+            }
+
+            if ((profile.getGroup().getName() == null || profile.getGroup().getName().equals("")) &&
+                    (profile.getGroup().getId() == null || profile.getGroup().getId().equals(""))) {
+                throw new MissingParameterException("Name or Id should not be null", null);
+            }
+
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + method);
+        }
+        return true;
+
+    }
+
+    private boolean validateGroupMembership(Object obj, String method) {
+        if (obj instanceof GroupMembership) {
+            GroupMembership profile = (GroupMembership) obj;
+
+            if (profile.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+
+            if (profile.getGroupId() == null || profile.getGroupId().equals("")) {
+                throw new MissingParameterException("Group Id be valid ", null);
+            }
+
+            if (profile.getUsername() == null || profile.getUsername().equals("")) {
+
+
+                throw new MissingParameterException("Username should not be null", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method " + method);
+        }
+        return true;
+
+    }
+
+
+    private boolean validateGetAllUserProfiles(Object obj, String method) {
+        if (obj instanceof UserProfileRequest) {
+            UserProfileRequest profileReq = (UserProfileRequest) obj;
+            if (profileReq.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method" + method);
+        }
+        return true;
+
+    }
+
+
+    private boolean validateGroupToGroupMembership(Object obj, String method) {
+        if (obj instanceof GroupToGroupMembership) {
+            GroupToGroupMembership profileReq = (GroupToGroupMembership) obj;
+            if (profileReq.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profileReq.getChildId() == null || profileReq.getChildId().trim().equals("")) {
+                throw new MissingParameterException("ChildId should not be null ", null);
+            }
+
+            if (profileReq.getParentId() == null || profileReq.getParentId().trim().equals("")) {
+                throw new MissingParameterException("ParentId should not be null ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method" + method);
+        }
+        return true;
+
+    }
+
+
+    private boolean validateGetAllGroupsOfUser(Object obj, String method) {
+        if (obj instanceof UserProfileRequest) {
+            UserProfileRequest profileReq = (UserProfileRequest) obj;
+            if (profileReq.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profileReq.getProfile() == null || profileReq.getProfile().getUsername() == null
+                    || profileReq.getProfile().getUsername().equals("")) {
+                throw new MissingParameterException("Username should not be null ", null);
+            }
+
+        } else {
+            throw new RuntimeException("Unexpected input type for method" + method);
+        }
+        return true;
+
+    }
+
+    private boolean validateGetAllParentGroupsOfGroup(Object obj, String method) {
+        if (obj instanceof GroupRequest) {
+            GroupRequest profileReq = (GroupRequest) obj;
+            if (profileReq.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profileReq.getGroup() == null || profileReq.getGroup().getId() == null
+                    || profileReq.getGroup().getId().equals("")) {
+                throw new MissingParameterException("groupId should not be null ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method" + method);
+        }
+        return true;
+    }
+
+
+    private boolean validateUserGroupMembershipTypeRequest(Object obj, String method) {
+        if (obj instanceof UserGroupMembershipTypeRequest) {
+            UserGroupMembershipTypeRequest profileReq = (UserGroupMembershipTypeRequest) obj;
+            if (profileReq.getType() == null
+                    || profileReq.getType().equals("")) {
+                throw new MissingParameterException("Membership type is null ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method" + method);
+        }
+        return true;
+
+    }
+
+
+    private boolean validateGetUserAndChildGroups(Object obj, String method) {
+        if (obj instanceof GroupRequest) {
+            GroupRequest profileReq = (GroupRequest) obj;
+            if (profileReq.getTenantId() == 0) {
+                throw new MissingParameterException("tenantId should be valid ", null);
+            }
+            if (profileReq.getGroup() == null || profileReq.getGroup().getId() == null
+                    || profileReq.getGroup().getId().equals("")) {
+                throw new MissingParameterException("groupId should not be null ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method" + method);
+        }
+        return true;
+    }
+
+
+}
diff --git a/custos-core-services/user-profile-core-service/src/main/proto/UserProfileService.proto b/custos-core-services/user-profile-core-service/src/main/proto/UserProfileService.proto
new file mode 100644
index 0000000..d4c9c56
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/proto/UserProfileService.proto
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.user.profile.service;
+
+
+enum UserStatus {
+    ACTIVE = 0;
+    CONFIRMED = 1;
+    APPROVED = 2;
+    DELETED = 3;
+    DUPLICATE = 4;
+    GRACE_PERIOD = 5;
+    INVITED = 6;
+    DENIED = 7;
+    PENDING = 8;
+    PENDING_APPROVAL = 9;
+    PENDING_CONFIRMATION = 10;
+    SUSPENDED = 11;
+    DECLINED = 12;
+    EXPIRED = 13;
+}
+
+enum DefaultGroupMembershipTypes {
+    OWNER = 0;
+    ADMIN = 1;
+    MEMBER = 2;
+}
+
+enum UserTypes {
+    END_USER = 0;
+    COMMUNITY = 1;
+}
+
+
+message UserProfile {
+    string username = 1;
+    string email = 2;
+    string first_name = 3;
+    string last_name = 4;
+    int64 created_at = 5;
+    UserStatus status = 6;
+    repeated UserAttribute attributes = 7;
+    repeated string client_roles = 8;
+    repeated string realm_roles = 9;
+    int64 last_modified_at = 10;
+    UserTypes type = 11;
+    DefaultGroupMembershipTypes membership_type = 12;
+}
+
+message UserProfileRequest {
+    int64 tenantId = 1;
+    UserProfile profile = 2;
+    string performedBy = 3;
+    string clientId = 4;
+}
+
+
+message UserAttribute {
+    int64 id = 1;
+    string key = 2;
+    repeated string value = 3;
+}
+
+
+message GetAllUserProfilesResponse {
+    repeated UserProfile profiles = 1;
+}
+
+message GetUpdateAuditTrailRequest {
+    int64 tenantId = 1;
+    string username = 2;
+}
+
+message UserProfileAttributeUpdateMetadata {
+    string updatedAttribute = 1;
+    string updatedAttributeValue = 2;
+    string updatedBy = 3;
+    string updatedAt = 4;
+}
+
+message UserProfileStatusUpdateMetadata {
+    UserStatus updatedStatus = 1;
+    string updatedBy = 2;
+    string updatedAt = 3;
+}
+
+message GetUpdateAuditTrailResponse {
+    repeated UserProfileAttributeUpdateMetadata attributeAudit = 1;
+    repeated UserProfileStatusUpdateMetadata statusAudit = 2;
+}
+
+message GroupRequest {
+    int64 tenantId = 1;
+    Group group = 2;
+    string performedBy = 3;
+    string clientId = 4;
+    DefaultGroupMembershipTypes membership_type = 5;
+
+}
+
+message GetAllGroupsResponse {
+    repeated Group groups = 1;
+}
+message Group {
+    string id = 1;
+    string name = 2;
+    repeated string realm_roles = 3;
+    repeated string client_roles = 4;
+    string parent_id = 5;
+    int64 created_time = 6;
+    int64 last_modified_time = 7;
+    repeated GroupAttribute attributes = 8;
+    string description = 9;
+    string owner_id = 10;
+}
+
+message GroupAttribute {
+    int64 id = 1;
+    string key = 2;
+    repeated string value = 3;
+}
+
+message GroupMembership {
+    int64 tenantId = 1;
+    string group_id = 2;
+    string username = 3;
+    string type = 4;
+    string clientId = 5;
+}
+
+message GroupToGroupMembership {
+    int64 tenantId = 1;
+    string parent_id = 2;
+    string child_id = 3;
+    string client_id = 4;
+}
+
+message Status {
+    bool status = 1;
+}
+
+message UserGroupMembershipTypeRequest {
+    string type = 1;
+}
+
+
+
+
+service UserProfileService {
+    rpc createUserProfile (UserProfileRequest) returns (UserProfile);
+    rpc updateUserProfile (UserProfileRequest) returns (UserProfile);
+    rpc getUserProfile (UserProfileRequest) returns (UserProfile);
+    rpc deleteUserProfile (UserProfileRequest) returns (UserProfile);
+    rpc getAllUserProfilesInTenant (UserProfileRequest) returns (GetAllUserProfilesResponse);
+    rpc findUserProfilesByAttributes (UserProfileRequest) returns (GetAllUserProfilesResponse);
+
+    rpc createGroup (GroupRequest) returns (Group);
+    rpc updateGroup (GroupRequest) returns (Group);
+    rpc deleteGroup (GroupRequest) returns (Group);
+    rpc getGroup (GroupRequest) returns (Group);
+    rpc getAllGroups (GroupRequest) returns (GetAllGroupsResponse);
+
+
+    rpc getUserProfileAuditTrails (GetUpdateAuditTrailRequest) returns (GetUpdateAuditTrailResponse);
+
+    rpc addUserToGroup (GroupMembership) returns (Status);
+    rpc removeUserFromGroup (GroupMembership) returns (Status);
+    rpc addChildGroupToParentGroup (GroupToGroupMembership) returns (Status);
+    rpc removeChildGroupFromParentGroup (GroupToGroupMembership) returns (Status);
+
+    rpc getAllGroupsOfUser (UserProfileRequest) returns (GetAllGroupsResponse);
+    rpc getAllParentGroupsOfGroup (GroupRequest) returns (GetAllGroupsResponse);
+
+    rpc addUserGroupMembershipType (UserGroupMembershipTypeRequest) returns (Status);
+    rpc removeUserGroupMembershipType (UserGroupMembershipTypeRequest) returns (Status);
+
+    rpc getAllChildUsers(GroupRequest) returns (GetAllUserProfilesResponse);
+    rpc getAllChildGroups(GroupRequest) returns (GetAllGroupsResponse);
+    rpc changeUserMembershipType (GroupMembership) returns (Status);
+    rpc hasAccess(GroupMembership) returns (Status);
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/custos-core-services/user-profile-core-service/src/main/resources/application.properties b/custos-core-services/user-profile-core-service/src/main/resources/application.properties
new file mode 100644
index 0000000..c045435
--- /dev/null
+++ b/custos-core-services/user-profile-core-service/src/main/resources/application.properties
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+grpc.port=7000
+server.port=8080
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.application.name=userProfileCoreService
+spring.sleuth.sampler.probability=1
+spring.main.allow-bean-definition-overriding=true
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+
+spring.datasource.url = jdbc:mysql://mysql.custos.svc.cluster.local:3306/core_user_profile?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
+spring.datasource.username = root
+spring.datasource.password = root
+
+
+## Hibernate Properties
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
+spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
+# Hibernate ddl auto (create, create-drop, validate, update)
+spring.jpa.hibernate.ddl-auto = update
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/Dockerfile b/custos-core-services/utility-services/custos-configuration-service/Dockerfile
new file mode 100644
index 0000000..a2b1503
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/pom.xml b/custos-core-services/utility-services/custos-configuration-service/pom.xml
new file mode 100644
index 0000000..6b0446d
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-core-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-configuration-service</artifactId>
+
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-config-server</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/.helmignore b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/Chart.yaml b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..fec15cf
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A helm of  custos configuration service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/NOTES.txt b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/_helpers.tpl b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/deployment.yaml b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..a040bc0
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,61 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: 9000
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: 9000
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/ingress.yaml b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..0c7cb5d
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helm.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: {{ $svcPort }}
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/service.yaml b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..5cb1350
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/serviceaccount.yaml b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/tests/test-connection.yaml b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/helm/values.yaml b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..13314d7
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/helm/values.yaml
@@ -0,0 +1,78 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 9000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/java/org/apache/custos/services/configuration/ConfigServer.java b/custos-core-services/utility-services/custos-configuration-service/src/main/java/org/apache/custos/services/configuration/ConfigServer.java
new file mode 100644
index 0000000..cfd2d16
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/java/org/apache/custos/services/configuration/ConfigServer.java
@@ -0,0 +1,13 @@
+package org.apache.custos.services.configuration;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.config.server.EnableConfigServer;
+
+@SpringBootApplication
+@EnableConfigServer
+public class ConfigServer {
+    public static void main(String[] args) {
+        SpringApplication.run(ConfigServer.class, args);
+    }
+}
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/agentManagementService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/agentManagementService.properties
new file mode 100644
index 0000000..d83afa8
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/agentManagementService.properties
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+agent.profile.core.service.dns.name=agent-profile-core-service.custos.svc.cluster.local
+agent.profile.core.service.port=7000
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+federated.authentication.service.dns.name=federeted-authentication-core-service.custos.svc.cluster.local
+federated.authentication.service.port=7000
+custos.logging.core.service.dns.name=custos-logging.custos.svc.cluster.local
+custos.logging.core.service.port=7000
+cluster.management.core.service.dns.name=cluster-management-core-service.custos.svc.cluster.local
+cluster.management.core.service.port=7000
+resource.secret.service.dns.name=resource-secret-core-service.custos.svc.cluster.local
+resource.secret.service.port=7000
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/application.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/application.properties
new file mode 100644
index 0000000..59c6cff
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+server.port=9000
+spring.profiles.active=native
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/clusterManagementCoreService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/clusterManagementCoreService.properties
new file mode 100644
index 0000000..a6df68b
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/clusterManagementCoreService.properties
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+custos.server.secret.name=tls-secret
+custos.server.kube.namespace=custos
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/federatedAuthenticationCoreService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/federatedAuthenticationCoreService.properties
new file mode 100644
index 0000000..dac040a
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/federatedAuthenticationCoreService.properties
@@ -0,0 +1,3 @@
+ciLogon.admin.client.id=XXXXX
+ciLogon.admin.client.secret=XXXX
+ciLogon.admin.auth.endpoint=https://test.cilogon.org/oauth2/oidc-cm
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/groupManagementService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/groupManagementService.properties
new file mode 100644
index 0000000..2993245
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/groupManagementService.properties
@@ -0,0 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+custos.logging.core.service.dns.name=custos-logging.custos.svc.cluster.local
+custos.logging.core.service.port=7000
+cluster.management.core.service.dns.name=cluster-management-core-service.custos.svc.cluster.local
+cluster.management.core.service.port=7000
+resource.secret.service.dns.name=resource-secret-core-service.custos.svc.cluster.local
+resource.secret.service.port=7000
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/iamAdminCoreService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/iamAdminCoreService.properties
new file mode 100644
index 0000000..5f7b569
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/iamAdminCoreService.properties
@@ -0,0 +1,23 @@
+iam.server.client.id=admin-cli
+iam.server.truststore.path=/home/ubuntu/keystore/keycloak-client-truststore.pkcs12
+iam.server.truststore.password=keycloak
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+iam.server.admin.username=XXXXXX
+iam.server.admin.password=XXXXXX
+iam.server.super.admin.realm.id=master
+iam.federated.cilogon.authorization.endpoint=https://cilogon.org/authorize
+iam.federated.cilogon.token.endpoint=https://cilogon.org/oauth2/token
+iam.federated.cilogon.token.userinfo.endpoint=https://cilogon.org/oauth2/userinfo
+iam.federated.cilogon.issuer=https://cilogon.org
+iam.federated.cilogon.jwksUri=https://cilogon.org/oauth2/certs
+introspection.endpoint=https://custos.scigap.org:32036/identity-management/v1.0.0/token/introspect
+issuer=https://custos.scigap.org/
+authorization.endpoint=https://custos.scigap.org/apiserver/identity-management/v1.0.0/authorize
+token.endpoint=https://custos.scigap.org/apiserver/identity-management/v1.0.0/token
+end.session.endpoint=https://custos.scigap.org/apiserver/identity-management/v1.0.0/logout
+user.info.endpoint=https://custos.scigap.org/apiserver/user-management/v1.0.0/userinfo
+jwks_uri=https://custos.scigap.org/apiserver/identity-management/v1.0.0/certs
+registration.endpoint=https://custos.scigap.org/apiserver/tenant-management/v1.0.0/oauth2/tenant
+ciLogon.admin.client.id=XXXXXXX
+ciLogon.admin.client.secret=XXXXXXXX
+ciLogon.admin.auth.endpoint=https://test.cilogon.org/oauth2/oidc-cm
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityCoreService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityCoreService.properties
new file mode 100644
index 0000000..61f1cfb
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityCoreService.properties
@@ -0,0 +1,44 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+custos.identity.auth.cache.enabled=true
+custos.identity.auth.cache.size=1024
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+iam.server.truststore.path=/home/ubuntu/keystore/keycloak-client-truststore.pkcs12
+iam.server.truststore.password=keycloak
+introspection.endpoint=https://custos.scigap.org:32036/identity-management/v1.0.0/token/introspect
+issuer=https://custos.scigap.org/
+authorization.endpoint=https://custos.scigap.org/apiserver/identity-management/v1.0.0/authorize
+token.endpoint=https://custos.scigap.org/apiserver/identity-management/v1.0.0/token
+end.session.endpoint=https://custos.scigap.org/apiserver/identity-management/v1.0.0/logout
+user.info.endpoint=https://custos.scigap.org/apiserver/user-management/v1.0.0/userinfo
+jwks_uri=https://custos.scigap.org/apiserver/identity-management/v1.0.0/certs
+registration.endpoint=https://custos.scigap.org:/apiserver/tenant-management/v1.0.0/oauth2/tenant
+iam.server.client.id=admin-cli
+iam.server.admin.username=XXXXXXX
+iam.server.admin.password=XXXXXXX
+iam.server.super.admin.realm.id=master
+iam.federated.cilogon.authorization.endpoint=https://cilogon.org/authorize
+iam.federated.cilogon.token.endpoint=https://cilogon.org/oauth2/token
+iam.federated.cilogon.token.userinfo.endpoint=https://cilogon.org/oauth2/userinfo
+iam.federated.cilogon.issuer=https://cilogon.org
+iam.federated.cilogon.jwksUri=https://cilogon.org/oauth2/certs
+ciLogon.admin.client.id=XXXXXXX
+ciLogon.admin.client.secret=XXXXXXXXX
+ciLogon.admin.auth.endpoint=https://test.cilogon.org/oauth2/oidc-cm
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityManagementService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityManagementService.properties
new file mode 100644
index 0000000..d62acbc
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityManagementService.properties
@@ -0,0 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+custos.logging.core.service.dns.name=custos-logging.custos.svc.cluster.local
+custos.logging.core.service.port=7000
+cluster.management.core.service.dns.name=cluster-management-core-service.custos.svc.cluster.local
+cluster.management.core.service.port=7000
+resource.secret.service.dns.name=resource-secret-core-service.custos.svc.cluster.local
+resource.secret.service.port=7000
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/logManagementService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/logManagementService.properties
new file mode 100644
index 0000000..11595f9
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/logManagementService.properties
@@ -0,0 +1,38 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+federated.authentication.service.dns.name=federeted-authentication-core-service.custos.svc.cluster.local
+federated.authentication.service.port=7000
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+custos.logging.core.service.dns.name=custos-logging.custos.svc.cluster.local
+custos.logging.core.service.port=7000
+cluster.management.core.service.dns.name=cluster-management-core-service.custos.svc.cluster.local
+cluster.management.core.service.port=7000
+resource.secret.service.dns.name=resource-secret-core-service.custos.svc.cluster.local
+resource.secret.service.port=7000
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/resourceSecretManagementService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/resourceSecretManagementService.properties
new file mode 100644
index 0000000..a6fe4f9
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/resourceSecretManagementService.properties
@@ -0,0 +1,38 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+federated.authentication.service.dns.name=federeted-authentication-core-service.custos.svc.cluster.local
+federated.authentication.service.port=7000
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+cluster.management.core.service.dns.name=cluster-management-core-service.custos.svc.cluster.local
+cluster.management.core.service.port=7000
+resource.secret.service.dns.name=resource-secret-core-service.custos.svc.cluster.local
+resource.secret.service.port=7000
+custos.logging.core.service.dns.name=custos-logging.custos.svc.cluster.local
+custos.logging.core.service.port=7000
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/scimService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/scimService.properties
new file mode 100644
index 0000000..63fb825
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/scimService.properties
@@ -0,0 +1,34 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+scim.resource.user.endpoint=https://custos.scigap.org:32036/scim/v2/Users
+scim.resource.group.endpoint=https://custos.scigap.org:32036/scim/v2/Groups
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+federated.authentication.service.dns.name=federeted-authentication-core-service.custos.svc.cluster.local
+federated.authentication.service.port=7000
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/sharingManagementService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/sharingManagementService.properties
new file mode 100644
index 0000000..c966d3c
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/sharingManagementService.properties
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+federated.authentication.service.dns.name=federeted-authentication-core-service.custos.svc.cluster.local
+federated.authentication.service.port=7000
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+sharing.core.service.dns.name=sharing-core-service.custos.svc.cluster.local
+sharing.core.service.port=7000
+custos.logging.core.service.dns.name=custos-logging.custos.svc.cluster.local
+custos.logging.core.service.port=7000
+cluster.management.core.service.dns.name=cluster-management-core-service.custos.svc.cluster.local
+cluster.management.core.service.port=7000
+resource.secret.service.dns.name=resource-secret-core-service.custos.svc.cluster.local
+resource.secret.service.port=7000
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/tenantManagementService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/tenantManagementService.properties
new file mode 100644
index 0000000..afccf04
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/tenantManagementService.properties
@@ -0,0 +1,19 @@
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+federated.authentication.service.dns.name=federeted-authentication-core-service.custos.svc.cluster.local
+federated.authentication.service.port=7000
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+custos.logging.core.service.dns.name=custos-logging.custos.svc.cluster.local
+custos.logging.core.service.port=7000
+cluster.management.core.service.dns.name=cluster-management-core-service.custos.svc.cluster.local
+cluster.management.core.service.port=7000
+resource.secret.service.dns.name=resource-secret-core-service.custos.svc.cluster.local
+resource.secret.service.port=7000
\ No newline at end of file
diff --git a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/userManagementService.properties b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/userManagementService.properties
new file mode 100644
index 0000000..32adfca
--- /dev/null
+++ b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/userManagementService.properties
@@ -0,0 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+custos.logging.core.service.dns.name=custos-logging.custos.svc.cluster.local
+custos.logging.core.service.port=7000
+cluster.management.core.service.dns.name=cluster-management-core-service.custos.svc.cluster.local
+cluster.management.core.service.port=7000
+resource.secret.service.dns.name=resource-secret-core-service.custos.svc.cluster.local
+resource.secret.service.port=7000
\ No newline at end of file
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/Dockerfile b/custos-external-services-distributions/custos-grpc-web-proxy/Dockerfile
new file mode 100644
index 0000000..ec5a702
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/Dockerfile
@@ -0,0 +1,2 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/envoy.yaml  /etc/envoy/envoy.yaml
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/pom.xml b/custos-external-services-distributions/custos-grpc-web-proxy/pom.xml
new file mode 100644
index 0000000..4193efb
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-external-services-distributions</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-grpc-web-proxy</artifactId>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/.helmignore b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/Chart.yaml b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..f2e32f5
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos grpc web proxy
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/NOTES.txt b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/_helpers.tpl b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/deployment.yaml b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..c864522
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,61 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+#        linkerd.io/inject: disabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: admin
+              containerPort: {{ .Values.proxy.adminport }}
+              protocol: TCP
+            - name: web
+              containerPort: {{ .Values.proxy.port }}
+              protocol: TCP
+          volumeMounts:
+            - name: tls-secret
+              mountPath: /etc/tls/tls-secret
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+      volumes:
+        - name: tls-secret
+          secret:
+             secretName: tls-secret
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/service.yaml b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..e2e1651
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/service.yaml
@@ -0,0 +1,29 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  annotations:
+    getambassador.io/config: |
+      ---
+      apiVersion: ambassador/v1
+      kind: Mapping
+      name: tenant-management-service-mapping
+      prefix: /tenant-management/
+      rewrite: ""
+      service: tenant-management-service.custos:50000
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.proxy.adminport }}
+      targetPort: admin
+      protocol: TCP
+      name: admin
+    - port: {{ .Values.proxy.port }}
+      targetPort: web
+      protocol: TCP
+      name: web
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/serviceaccount.yaml b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/tests/test-connection.yaml b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/values.yaml b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/values.yaml
new file mode 100644
index 0000000..5752474
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/helm/values.yaml
@@ -0,0 +1,89 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+role:
+  name: resource-fetch
+  binding: resource-role-binder
+
+
+proxy:
+   repository: apachecustos/${artifactId}
+   tag: ${project.version}
+   port: 40000
+   adminport: 9901
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-external-services-distributions/custos-grpc-web-proxy/src/main/resources/envoy.yaml b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..93cab9a
--- /dev/null
+++ b/custos-external-services-distributions/custos-grpc-web-proxy/src/main/resources/envoy.yaml
@@ -0,0 +1,113 @@
+admin:
+  access_log_path: /tmp/admin_access.log
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+  listeners:
+    - name: web-listner
+      address:
+        socket_address: { address: 0.0.0.0, port_value: 40000 }
+      filter_chains:
+        - filters:
+            - name: envoy.http_connection_manager
+              config:
+                codec_type: auto
+                stat_prefix: ingress_http
+                route_config:
+                  name: local_route
+                  virtual_hosts:
+                    - name: local_service
+                      domains: ["*"]
+                      routes:
+                        - match: { prefix: "/org.apache.custos.resource.secret.management.service.ResourceSecretManagementService" }
+                          route: { cluster: resource-secret-backend-service }
+                        - match: { prefix: "/org.apache.custos.agent.management.service.AgentManagementService" }
+                          route: { cluster: agent-management-backend-service }
+                        - match: { prefix: "/org.apache.custos.group.management.service.GroupManagementService" }
+                          route: { cluster: group-management-service-backend-service }
+                        - match: { prefix: "/org.apache.custos.identity.management.service.IdentityManagementService" }
+                          route: { cluster: identity-management-service-backend-service }
+                        - match: { prefix: "/org.apache.custos.tenant.management.service.TenantManagementService" }
+                          route: { cluster: tenant-management-service-backend-service }
+                        - match: { prefix: "/org.apache.custos.user.management.service.UserManagementService" }
+                          route: { cluster: user-management-service-backend-service }
+                http_filters:
+                  - name: envoy.grpc_web
+                  - name: envoy.router
+          transport_socket:
+            name: envoy.transport_sockets.tls
+            typed_config:
+              "@type": type.googleapis.com/envoy.api.v2.auth.DownstreamTlsContext
+              common_tls_context:
+                tls_certificates:
+                    - certificate_chain:
+                        filename: "/etc/tls/tls-secret/tls.crt"
+                      private_key:
+                        filename: "/etc/tls/tls-secret/tls.key"
+  clusters:
+    - name: resource-secret-backend-service
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: resource-secret-management-service.custos.svc.cluster.local
+            port_value: 7000
+
+    - name: agent-management-backend-service
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: agent-management-service.custos.svc.cluster.local
+            port_value: 7000
+
+    - name: group-management-service-backend-service
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: group-management-service.custos.svc.cluster.local
+            port_value: 7000
+
+    - name: identity-management-service-backend-service
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: identity-management-service.custos.svc.cluster.local
+            port_value: 7000
+
+    - name: tenant-management-service-backend-service
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: tenant-management-service.custos.svc.cluster.local
+            port_value: 7000
+
+    - name: user-management-service-backend-service
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: user-management-service.custos.svc.cluster.local
+            port_value: 7000
diff --git a/custos-external-services-distributions/custos-keycloak/Dockerfile b/custos-external-services-distributions/custos-keycloak/Dockerfile
new file mode 100644
index 0000000..58d8531
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/Dockerfile
@@ -0,0 +1,4 @@
+FROM jboss/keycloak:7.0.0
+COPY src/main/resources/standalone-ha.xml /opt/jboss/keycloak/standalone/configuration/standalone-ha.xml
+COPY src/main/resources/standalone.xml /opt/jboss/keycloak/standalone/configuration/standalone.xml
+COPY src/main/resources/themes  /opt/jboss/keycloak/themes/
\ No newline at end of file
diff --git a/custos-external-services-distributions/custos-keycloak/pom.xml b/custos-external-services-distributions/custos-keycloak/pom.xml
new file mode 100644
index 0000000..37a7dba
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-external-services-distributions</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-keycloak</artifactId>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-external-services-distributions/custos-keycloak/src/main/resources/standalone-ha.xml b/custos-external-services-distributions/custos-keycloak/src/main/resources/standalone-ha.xml
new file mode 100644
index 0000000..4e99163
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/src/main/resources/standalone-ha.xml
@@ -0,0 +1,657 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<server xmlns="urn:jboss:domain:10.0">
+    <extensions>
+        <extension module="org.jboss.as.clustering.infinispan"/>
+        <extension module="org.jboss.as.clustering.jgroups"/>
+        <extension module="org.jboss.as.connector"/>
+        <extension module="org.jboss.as.deployment-scanner"/>
+        <extension module="org.jboss.as.ee"/>
+        <extension module="org.jboss.as.ejb3"/>
+        <extension module="org.jboss.as.jaxrs"/>
+        <extension module="org.jboss.as.jmx"/>
+        <extension module="org.jboss.as.jpa"/>
+        <extension module="org.jboss.as.logging"/>
+        <extension module="org.jboss.as.mail"/>
+        <extension module="org.jboss.as.modcluster"/>
+        <extension module="org.jboss.as.naming"/>
+        <extension module="org.jboss.as.remoting"/>
+        <extension module="org.jboss.as.security"/>
+        <extension module="org.jboss.as.transactions"/>
+        <extension module="org.jboss.as.weld"/>
+        <extension module="org.keycloak.keycloak-server-subsystem"/>
+        <extension module="org.wildfly.extension.bean-validation"/>
+        <extension module="org.wildfly.extension.core-management"/>
+        <extension module="org.wildfly.extension.elytron"/>
+        <extension module="org.wildfly.extension.io"/>
+        <extension module="org.wildfly.extension.microprofile.config-smallrye"/>
+        <extension module="org.wildfly.extension.microprofile.health-smallrye"/>
+        <extension module="org.wildfly.extension.microprofile.metrics-smallrye"/>
+        <extension module="org.wildfly.extension.request-controller"/>
+        <extension module="org.wildfly.extension.security.manager"/>
+        <extension module="org.wildfly.extension.undertow"/>
+    </extensions>
+    <management>
+        <security-realms>
+            <security-realm name="ManagementRealm">
+                <authentication>
+                    <local default-user="$local" skip-group-loading="true"/>
+                    <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
+                </authentication>
+                <authorization map-groups-to-roles="false">
+                    <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+                </authorization>
+            </security-realm>
+            <security-realm name="ApplicationRealm">
+                <server-identities>
+                    <ssl>
+                        <keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
+                    </ssl>
+                </server-identities>
+                <authentication>
+                    <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
+                    <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
+                </authentication>
+                <authorization>
+                    <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+                </authorization>
+            </security-realm>
+        </security-realms>
+        <audit-log>
+            <formatters>
+                <json-formatter name="json-formatter"/>
+            </formatters>
+            <handlers>
+                <file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
+            </handlers>
+            <logger log-boot="true" log-read-only="false" enabled="false">
+                <handlers>
+                    <handler name="file"/>
+                </handlers>
+            </logger>
+        </audit-log>
+        <management-interfaces>
+            <http-interface security-realm="ManagementRealm">
+                <http-upgrade enabled="true"/>
+                <socket-binding http="management-http"/>
+            </http-interface>
+        </management-interfaces>
+        <access-control provider="simple">
+            <role-mapping>
+                <role name="SuperUser">
+                    <include>
+                        <user name="$local"/>
+                    </include>
+                </role>
+            </role-mapping>
+        </access-control>
+    </management>
+    <profile>
+        <subsystem xmlns="urn:jboss:domain:logging:7.0">
+            <console-handler name="CONSOLE">
+                <formatter>
+                    <named-formatter name="COLOR-PATTERN"/>
+                </formatter>
+            </console-handler>
+            <logger category="com.arjuna">
+                <level name="WARN"/>
+            </logger>
+            <logger category="io.jaegertracing.Configuration">
+                <level name="WARN"/>
+            </logger>
+            <logger category="org.jboss.as.config">
+                <level name="DEBUG"/>
+            </logger>
+            <logger category="sun.rmi">
+                <level name="WARN"/>
+            </logger>
+            <logger category="org.keycloak">
+                <level name="${env.KEYCLOAK_LOGLEVEL:INFO}"/>
+            </logger>
+            <root-logger>
+                <level name="${env.ROOT_LOGLEVEL:INFO}"/>
+                <handlers>
+                    <handler name="CONSOLE"/>
+                </handlers>
+            </root-logger>
+            <formatter name="PATTERN">
+                <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+            </formatter>
+            <formatter name="COLOR-PATTERN">
+                <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+            </formatter>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
+        <subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
+        <subsystem xmlns="urn:jboss:domain:datasources:5.0">
+            <datasources>
+                <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
+                    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
+                    <driver>h2</driver>
+                    <security>
+                        <user-name>sa</user-name>
+                        <password>sa</password>
+                    </security>
+                </datasource>
+                <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
+                    <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
+                    <driver>h2</driver>
+                    <security>
+                        <user-name>sa</user-name>
+                        <password>sa</password>
+                    </security>
+                </datasource>
+                <drivers>
+                    <driver name="h2" module="com.h2database.h2">
+                        <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
+                    </driver>
+                </drivers>
+            </datasources>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
+            <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:ee:4.0">
+            <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
+            <concurrent>
+                <context-services>
+                    <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
+                </context-services>
+                <managed-thread-factories>
+                    <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
+                </managed-thread-factories>
+                <managed-executor-services>
+                    <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
+                </managed-executor-services>
+                <managed-scheduled-executor-services>
+                    <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
+                </managed-scheduled-executor-services>
+            </concurrent>
+            <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:ejb3:5.0">
+            <session-bean>
+                <stateless>
+                    <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
+                </stateless>
+                <stateful default-access-timeout="5000" cache-ref="distributable" passivation-disabled-cache-ref="simple"/>
+                <singleton default-access-timeout="5000"/>
+            </session-bean>
+            <pools>
+                <bean-instance-pools>
+                    <strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+                    <strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+                </bean-instance-pools>
+            </pools>
+            <caches>
+                <cache name="simple"/>
+                <cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
+            </caches>
+            <passivation-stores>
+                <passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
+            </passivation-stores>
+            <async thread-pool-name="default"/>
+            <timer-service thread-pool-name="default" default-data-store="default-file-store">
+                <data-stores>
+                    <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
+                </data-stores>
+            </timer-service>
+            <remote connector-ref="http-remoting-connector" thread-pool-name="default">
+                <channel-creation-options>
+                    <option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
+                </channel-creation-options>
+            </remote>
+            <thread-pools>
+                <thread-pool name="default">
+                    <max-threads count="10"/>
+                    <keepalive-time time="100" unit="milliseconds"/>
+                </thread-pool>
+            </thread-pools>
+            <default-security-domain value="other"/>
+            <default-missing-method-permissions-deny-access value="true"/>
+            <statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
+            <log-system-exceptions value="true"/>
+        </subsystem>
+        <subsystem xmlns="urn:wildfly:elytron:7.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
+            <providers>
+                <aggregate-providers name="combined-providers">
+                    <providers name="elytron"/>
+                    <providers name="openssl"/>
+                </aggregate-providers>
+                <provider-loader name="elytron" module="org.wildfly.security.elytron"/>
+                <provider-loader name="openssl" module="org.wildfly.openssl"/>
+            </providers>
+            <audit-logging>
+                <file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
+            </audit-logging>
+            <security-domains>
+                <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
+                    <realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
+                    <realm name="local"/>
+                </security-domain>
+                <security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
+                    <realm name="ManagementRealm" role-decoder="groups-to-roles"/>
+                    <realm name="local" role-mapper="super-user-mapper"/>
+                </security-domain>
+            </security-domains>
+            <security-realms>
+                <identity-realm name="local" identity="$local"/>
+                <properties-realm name="ApplicationRealm">
+                    <users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
+                    <groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+                </properties-realm>
+                <properties-realm name="ManagementRealm">
+                    <users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
+                    <groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+                </properties-realm>
+            </security-realms>
+            <mappers>
+                <simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
+                    <permission-mapping>
+                        <principal name="anonymous"/>
+                        <permission-set name="default-permissions"/>
+                    </permission-mapping>
+                    <permission-mapping match-all="true">
+                        <permission-set name="login-permission"/>
+                        <permission-set name="default-permissions"/>
+                    </permission-mapping>
+                </simple-permission-mapper>
+                <constant-realm-mapper name="local" realm-name="local"/>
+                <simple-role-decoder name="groups-to-roles" attribute="groups"/>
+                <constant-role-mapper name="super-user-mapper">
+                    <role name="SuperUser"/>
+                </constant-role-mapper>
+            </mappers>
+            <permission-sets>
+                <permission-set name="login-permission">
+                    <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
+                </permission-set>
+                <permission-set name="default-permissions">
+                    <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+                    <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+                    <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+                </permission-set>
+            </permission-sets>
+            <http>
+                <http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global">
+                    <mechanism-configuration>
+                        <mechanism mechanism-name="DIGEST">
+                            <mechanism-realm realm-name="ManagementRealm"/>
+                        </mechanism>
+                    </mechanism-configuration>
+                </http-authentication-factory>
+                <provider-http-server-mechanism-factory name="global"/>
+            </http>
+            <sasl>
+                <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
+                    <mechanism-configuration>
+                        <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+                        <mechanism mechanism-name="DIGEST-MD5">
+                            <mechanism-realm realm-name="ApplicationRealm"/>
+                        </mechanism>
+                    </mechanism-configuration>
+                </sasl-authentication-factory>
+                <sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
+                    <mechanism-configuration>
+                        <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+                        <mechanism mechanism-name="DIGEST-MD5">
+                            <mechanism-realm realm-name="ManagementRealm"/>
+                        </mechanism>
+                    </mechanism-configuration>
+                </sasl-authentication-factory>
+                <configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
+                    <properties>
+                        <property name="wildfly.sasl.local-user.default-user" value="$local"/>
+                    </properties>
+                </configurable-sasl-server-factory>
+                <mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
+                    <filters>
+                        <filter provider-name="WildFlyElytron"/>
+                    </filters>
+                </mechanism-provider-filtering-sasl-server-factory>
+                <provider-sasl-server-factory name="global"/>
+            </sasl>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:infinispan:8.0">
+            <cache-container name="keycloak">
+                <transport lock-timeout="60000"/>
+                <local-cache name="realms">
+                    <object-memory size="10000"/>
+                </local-cache>
+                <local-cache name="users">
+                    <object-memory size="10000"/>
+                </local-cache>
+                <local-cache name="authorization">
+                    <object-memory size="10000"/>
+                </local-cache>
+                <local-cache name="keys">
+                    <object-memory size="1000"/>
+                    <expiration max-idle="3600000"/>
+                </local-cache>
+                <replicated-cache name="work"/>
+                <distributed-cache name="sessions" owners="1"/>
+                <distributed-cache name="authenticationSessions" owners="1"/>
+                <distributed-cache name="offlineSessions" owners="1"/>
+                <distributed-cache name="clientSessions" owners="1"/>
+                <distributed-cache name="offlineClientSessions" owners="1"/>
+                <distributed-cache name="loginFailures" owners="1"/>
+                <distributed-cache name="actionTokens" owners="2">
+                    <object-memory size="-1"/>
+                    <expiration interval="300000" max-idle="-1"/>
+                </distributed-cache>
+            </cache-container>
+            <cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
+                <transport lock-timeout="60000"/>
+                <replicated-cache name="default">
+                    <transaction mode="BATCH"/>
+                </replicated-cache>
+            </cache-container>
+            <cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan">
+                <transport lock-timeout="60000"/>
+                <replicated-cache name="sso">
+                    <locking isolation="REPEATABLE_READ"/>
+                    <transaction mode="BATCH"/>
+                </replicated-cache>
+                <distributed-cache name="dist">
+                    <locking isolation="REPEATABLE_READ"/>
+                    <transaction mode="BATCH"/>
+                    <file-store/>
+                </distributed-cache>
+                <distributed-cache name="routing"/>
+            </cache-container>
+            <cache-container name="ejb" aliases="sfsb" default-cache="dist" module="org.wildfly.clustering.ejb.infinispan">
+                <transport lock-timeout="60000"/>
+                <distributed-cache name="dist">
+                    <locking isolation="REPEATABLE_READ"/>
+                    <transaction mode="BATCH"/>
+                    <file-store/>
+                </distributed-cache>
+            </cache-container>
+            <cache-container name="hibernate" module="org.infinispan.hibernate-cache">
+                <transport lock-timeout="60000"/>
+                <local-cache name="local-query">
+                    <object-memory size="10000"/>
+                    <expiration max-idle="100000"/>
+                </local-cache>
+                <invalidation-cache name="entity">
+                    <transaction mode="NON_XA"/>
+                    <object-memory size="10000"/>
+                    <expiration max-idle="100000"/>
+                </invalidation-cache>
+                <replicated-cache name="timestamps"/>
+            </cache-container>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:io:3.0">
+            <worker name="default"/>
+            <buffer-pool name="default"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
+        <subsystem xmlns="urn:jboss:domain:jca:5.0">
+            <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
+            <bean-validation enabled="true"/>
+            <default-workmanager>
+                <short-running-threads>
+                    <core-threads count="50"/>
+                    <queue-length count="50"/>
+                    <max-threads count="50"/>
+                    <keepalive-time time="10" unit="seconds"/>
+                </short-running-threads>
+                <long-running-threads>
+                    <core-threads count="50"/>
+                    <queue-length count="50"/>
+                    <max-threads count="50"/>
+                    <keepalive-time time="10" unit="seconds"/>
+                </long-running-threads>
+            </default-workmanager>
+            <cached-connection-manager/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:jgroups:7.0">
+            <channels default="ee">
+                <channel name="ee" stack="udp" cluster="ejb"/>
+            </channels>
+            <stacks>
+                <stack name="udp">
+                    <transport type="UDP" socket-binding="jgroups-udp"/>
+                    <protocol type="PING"/>
+                    <protocol type="MERGE3"/>
+                    <socket-protocol type="FD_SOCK" socket-binding="jgroups-udp-fd"/>
+                    <protocol type="FD_ALL"/>
+                    <protocol type="VERIFY_SUSPECT"/>
+                    <protocol type="pbcast.NAKACK2"/>
+                    <protocol type="UNICAST3"/>
+                    <protocol type="pbcast.STABLE"/>
+                    <protocol type="pbcast.GMS"/>
+                    <protocol type="UFC"/>
+                    <protocol type="MFC"/>
+                    <protocol type="FRAG3"/>
+                </stack>
+                <stack name="tcp">
+                    <transport type="TCP" socket-binding="jgroups-tcp"/>
+                    <socket-protocol type="MPING" socket-binding="jgroups-mping"/>
+                    <protocol type="MERGE3"/>
+                    <socket-protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/>
+                    <protocol type="FD_ALL"/>
+                    <protocol type="VERIFY_SUSPECT"/>
+                    <protocol type="pbcast.NAKACK2"/>
+                    <protocol type="UNICAST3"/>
+                    <protocol type="pbcast.STABLE"/>
+                    <protocol type="pbcast.GMS"/>
+                    <protocol type="MFC"/>
+                    <protocol type="FRAG3"/>
+                </stack>
+            </stacks>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:jmx:1.3">
+            <expose-resolved-model/>
+            <expose-expression-model/>
+            <remoting-connector/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:jpa:1.1">
+            <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+            <web-context>auth</web-context>
+            <providers>
+                <provider>
+                    classpath:${jboss.home.dir}/providers/*
+                </provider>
+            </providers>
+            <master-realm-name>master</master-realm-name>
+            <scheduled-task-interval>900</scheduled-task-interval>
+            <theme>
+                <staticMaxAge>-1</staticMaxAge>
+                <cacheThemes>false</cacheThemes>
+                <cacheTemplates>false</cacheTemplates>
+                <welcomeTheme>${env.KEYCLOAK_WELCOME_THEME:keycloak}</welcomeTheme>
+                <default>${env.KEYCLOAK_DEFAULT_THEME:keycloak}</default>
+                <dir>${jboss.home.dir}/themes</dir>
+            </theme>
+            <spi name="eventsStore">
+                <provider name="jpa" enabled="true">
+                    <properties>
+                        <property name="exclude-events" value="[&quot;REFRESH_TOKEN&quot;]"/>
+                    </properties>
+                </provider>
+            </spi>
+            <spi name="userCache">
+                <provider name="default" enabled="true"/>
+            </spi>
+            <spi name="userSessionPersister">
+                <default-provider>jpa</default-provider>
+            </spi>
+            <spi name="timer">
+                <default-provider>basic</default-provider>
+            </spi>
+            <spi name="connectionsHttpClient">
+                <provider name="default" enabled="true"/>
+            </spi>
+            <spi name="connectionsJpa">
+                <provider name="default" enabled="true">
+                    <properties>
+                        <property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
+                        <property name="initializeEmpty" value="true"/>
+                        <property name="migrationStrategy" value="update"/>
+                        <property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
+                    </properties>
+                </provider>
+            </spi>
+            <spi name="realmCache">
+                <provider name="default" enabled="true"/>
+            </spi>
+            <spi name="connectionsInfinispan">
+                <default-provider>default</default-provider>
+                <provider name="default" enabled="true">
+                    <properties>
+                        <property name="cacheContainer" value="java:jboss/infinispan/container/keycloak"/>
+                    </properties>
+                </provider>
+            </spi>
+            <spi name="jta-lookup">
+                <default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
+                <provider name="jboss" enabled="true"/>
+            </spi>
+            <spi name="publicKeyStorage">
+                <provider name="infinispan" enabled="true">
+                    <properties>
+                        <property name="minTimeBetweenRequests" value="10"/>
+                    </properties>
+                </provider>
+            </spi>
+            <spi name="x509cert-lookup">
+                <default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
+                <provider name="default" enabled="true"/>
+            </spi>
+            <spi name="hostname">
+                <default-provider>${keycloak.hostname.provider:request}</default-provider>
+                <provider name="fixed" enabled="true">
+                    <properties>
+                        <property name="hostname" value="${keycloak.hostname.fixed.hostname:localhost}"/>
+                        <property name="httpPort" value="${keycloak.hostname.fixed.httpPort:-1}"/>
+                        <property name="httpsPort" value="${keycloak.hostname.fixed.httpsPort:-1}"/>
+                        <property name="alwaysHttps" value="${keycloak.hostname.fixed.alwaysHttps:false}"/>
+                    </properties>
+                </provider>
+            </spi>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:mail:3.0">
+            <mail-session name="default" jndi-name="java:jboss/mail/Default">
+                <smtp-server outbound-socket-binding-ref="mail-smtp"/>
+            </mail-session>
+        </subsystem>
+        <subsystem xmlns="urn:wildfly:microprofile-config-smallrye:1.0"/>
+        <subsystem xmlns="urn:wildfly:microprofile-health-smallrye:1.0" security-enabled="false"/>
+        <subsystem xmlns="urn:wildfly:microprofile-metrics-smallrye:2.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:wildfly}"/>
+        <subsystem xmlns="urn:jboss:domain:modcluster:5.0">
+            <proxy name="default" advertise-socket="modcluster" listener="ajp">
+                <dynamic-load-provider>
+                    <load-metric type="cpu"/>
+                </dynamic-load-provider>
+            </proxy>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:naming:2.0">
+            <remote-naming/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:remoting:4.0">
+            <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
+        <subsystem xmlns="urn:jboss:domain:security:2.0">
+            <security-domains>
+                <security-domain name="other" cache-type="default">
+                    <authentication>
+                        <login-module code="Remoting" flag="optional">
+                            <module-option name="password-stacking" value="useFirstPass"/>
+                        </login-module>
+                        <login-module code="RealmDirect" flag="required">
+                            <module-option name="password-stacking" value="useFirstPass"/>
+                        </login-module>
+                    </authentication>
+                </security-domain>
+                <security-domain name="jboss-web-policy" cache-type="default">
+                    <authorization>
+                        <policy-module code="Delegating" flag="required"/>
+                    </authorization>
+                </security-domain>
+                <security-domain name="jaspitest" cache-type="default">
+                    <authentication-jaspi>
+                        <login-module-stack name="dummy">
+                            <login-module code="Dummy" flag="optional"/>
+                        </login-module-stack>
+                        <auth-module code="Dummy"/>
+                    </authentication-jaspi>
+                </security-domain>
+                <security-domain name="jboss-ejb-policy" cache-type="default">
+                    <authorization>
+                        <policy-module code="Delegating" flag="required"/>
+                    </authorization>
+                </security-domain>
+            </security-domains>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:security-manager:1.0">
+            <deployment-permissions>
+                <maximum-set>
+                    <permission class="java.security.AllPermission"/>
+                </maximum-set>
+            </deployment-permissions>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:transactions:5.0">
+            <core-environment node-identifier="${jboss.tx.node.id:1}">
+                <process-id>
+                    <uuid/>
+                </process-id>
+            </core-environment>
+            <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
+            <coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
+            <object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:undertow:9.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
+            <buffer-cache name="default"/>
+            <server name="default-server">
+                <ajp-listener name="ajp" socket-binding="ajp"/>
+                <http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="${env.PROXY_ADDRESS_FORWARDING:false}" enable-http2="true"/>
+                <https-listener name="https" socket-binding="https" proxy-address-forwarding="${env.PROXY_ADDRESS_FORWARDING:false}" security-realm="ApplicationRealm" enable-http2="true"/>
+                <host name="default-host" alias="localhost">
+                    <location name="/" handler="welcome-content"/>
+                    <http-invoker security-realm="ApplicationRealm"/>
+                </host>
+            </server>
+            <servlet-container name="default">
+                <jsp-config/>
+                <websockets/>
+            </servlet-container>
+            <handlers>
+                <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
+            </handlers>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:weld:4.0"/>
+    </profile>
+    <interfaces>
+        <interface name="management">
+            <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
+        </interface>
+        <interface name="public">
+            <inet-address value="${jboss.bind.address:127.0.0.1}"/>
+        </interface>
+        <interface name="private">
+            <inet-address value="${jboss.bind.address.private:127.0.0.1}"/>
+        </interface>
+    </interfaces>
+    <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
+        <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
+        <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
+        <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
+        <socket-binding name="http" port="${jboss.http.port:8080}"/>
+        <socket-binding name="https" port="${jboss.https.port:8443}"/>
+        <socket-binding name="jgroups-mping" interface="private" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45700"/>
+        <socket-binding name="jgroups-tcp" interface="private" port="7600"/>
+        <socket-binding name="jgroups-tcp-fd" interface="private" port="57600"/>
+        <socket-binding name="jgroups-udp" interface="private" port="55200" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45688"/>
+        <socket-binding name="jgroups-udp-fd" interface="private" port="54200"/>
+        <socket-binding name="modcluster" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>
+        <socket-binding name="txn-recovery-environment" port="4712"/>
+        <socket-binding name="txn-status-manager" port="4713"/>
+        <outbound-socket-binding name="mail-smtp">
+            <remote-destination host="localhost" port="25"/>
+        </outbound-socket-binding>
+    </socket-binding-group>
+</server>
\ No newline at end of file
diff --git a/custos-external-services-distributions/custos-keycloak/src/main/resources/standalone.xml b/custos-external-services-distributions/custos-keycloak/src/main/resources/standalone.xml
new file mode 100644
index 0000000..dd2690d
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/src/main/resources/standalone.xml
@@ -0,0 +1,596 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<server xmlns="urn:jboss:domain:10.0">
+    <extensions>
+        <extension module="org.jboss.as.clustering.infinispan"/>
+        <extension module="org.jboss.as.connector"/>
+        <extension module="org.jboss.as.deployment-scanner"/>
+        <extension module="org.jboss.as.ee"/>
+        <extension module="org.jboss.as.ejb3"/>
+        <extension module="org.jboss.as.jaxrs"/>
+        <extension module="org.jboss.as.jmx"/>
+        <extension module="org.jboss.as.jpa"/>
+        <extension module="org.jboss.as.logging"/>
+        <extension module="org.jboss.as.mail"/>
+        <extension module="org.jboss.as.naming"/>
+        <extension module="org.jboss.as.remoting"/>
+        <extension module="org.jboss.as.security"/>
+        <extension module="org.jboss.as.transactions"/>
+        <extension module="org.jboss.as.weld"/>
+        <extension module="org.keycloak.keycloak-server-subsystem"/>
+        <extension module="org.wildfly.extension.bean-validation"/>
+        <extension module="org.wildfly.extension.core-management"/>
+        <extension module="org.wildfly.extension.elytron"/>
+        <extension module="org.wildfly.extension.io"/>
+        <extension module="org.wildfly.extension.microprofile.config-smallrye"/>
+        <extension module="org.wildfly.extension.microprofile.health-smallrye"/>
+        <extension module="org.wildfly.extension.microprofile.metrics-smallrye"/>
+        <extension module="org.wildfly.extension.request-controller"/>
+        <extension module="org.wildfly.extension.security.manager"/>
+        <extension module="org.wildfly.extension.undertow"/>
+    </extensions>
+    <management>
+        <security-realms>
+            <security-realm name="ManagementRealm">
+                <authentication>
+                    <local default-user="$local" skip-group-loading="true"/>
+                    <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
+                </authentication>
+                <authorization map-groups-to-roles="false">
+                    <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+                </authorization>
+            </security-realm>
+            <security-realm name="ApplicationRealm">
+                <server-identities>
+                    <ssl>
+                        <keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
+                    </ssl>
+                </server-identities>
+                <authentication>
+                    <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
+                    <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
+                </authentication>
+                <authorization>
+                    <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+                </authorization>
+            </security-realm>
+        </security-realms>
+        <audit-log>
+            <formatters>
+                <json-formatter name="json-formatter"/>
+            </formatters>
+            <handlers>
+                <file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
+            </handlers>
+            <logger log-boot="true" log-read-only="false" enabled="false">
+                <handlers>
+                    <handler name="file"/>
+                </handlers>
+            </logger>
+        </audit-log>
+        <management-interfaces>
+            <http-interface security-realm="ManagementRealm">
+                <http-upgrade enabled="true"/>
+                <socket-binding http="management-http"/>
+            </http-interface>
+        </management-interfaces>
+        <access-control provider="simple">
+            <role-mapping>
+                <role name="SuperUser">
+                    <include>
+                        <user name="$local"/>
+                    </include>
+                </role>
+            </role-mapping>
+        </access-control>
+    </management>
+    <profile>
+        <subsystem xmlns="urn:jboss:domain:logging:7.0">
+            <console-handler name="CONSOLE">
+                <formatter>
+                    <named-formatter name="COLOR-PATTERN"/>
+                </formatter>
+            </console-handler>
+            <logger category="com.arjuna">
+                <level name="WARN"/>
+            </logger>
+            <logger category="io.jaegertracing.Configuration">
+                <level name="WARN"/>
+            </logger>
+            <logger category="org.jboss.as.config">
+                <level name="DEBUG"/>
+            </logger>
+            <logger category="sun.rmi">
+                <level name="WARN"/>
+            </logger>
+            <logger category="org.keycloak">
+                <level name="${env.KEYCLOAK_LOGLEVEL:INFO}"/>
+            </logger>
+            <root-logger>
+                <level name="${env.ROOT_LOGLEVEL:INFO}"/>
+                <handlers>
+                    <handler name="CONSOLE"/>
+                </handlers>
+            </root-logger>
+            <formatter name="PATTERN">
+                <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+            </formatter>
+            <formatter name="COLOR-PATTERN">
+                <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+            </formatter>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
+        <subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
+        <subsystem xmlns="urn:jboss:domain:datasources:5.0">
+            <datasources>
+                <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
+                    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
+                    <driver>h2</driver>
+                    <security>
+                        <user-name>sa</user-name>
+                        <password>sa</password>
+                    </security>
+                </datasource>
+                <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
+                    <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
+                    <driver>h2</driver>
+                    <security>
+                        <user-name>sa</user-name>
+                        <password>sa</password>
+                    </security>
+                </datasource>
+                <drivers>
+                    <driver name="h2" module="com.h2database.h2">
+                        <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
+                    </driver>
+                </drivers>
+            </datasources>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
+            <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:ee:4.0">
+            <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
+            <concurrent>
+                <context-services>
+                    <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
+                </context-services>
+                <managed-thread-factories>
+                    <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
+                </managed-thread-factories>
+                <managed-executor-services>
+                    <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
+                </managed-executor-services>
+                <managed-scheduled-executor-services>
+                    <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
+                </managed-scheduled-executor-services>
+            </concurrent>
+            <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:ejb3:5.0">
+            <session-bean>
+                <stateless>
+                    <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
+                </stateless>
+                <stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
+                <singleton default-access-timeout="5000"/>
+            </session-bean>
+            <pools>
+                <bean-instance-pools>
+                    <strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+                    <strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+                </bean-instance-pools>
+            </pools>
+            <caches>
+                <cache name="simple"/>
+                <cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
+            </caches>
+            <passivation-stores>
+                <passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
+            </passivation-stores>
+            <async thread-pool-name="default"/>
+            <timer-service thread-pool-name="default" default-data-store="default-file-store">
+                <data-stores>
+                    <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
+                </data-stores>
+            </timer-service>
+            <remote connector-ref="http-remoting-connector" thread-pool-name="default">
+                <channel-creation-options>
+                    <option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
+                </channel-creation-options>
+            </remote>
+            <thread-pools>
+                <thread-pool name="default">
+                    <max-threads count="10"/>
+                    <keepalive-time time="100" unit="milliseconds"/>
+                </thread-pool>
+            </thread-pools>
+            <default-security-domain value="other"/>
+            <default-missing-method-permissions-deny-access value="true"/>
+            <statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
+            <log-system-exceptions value="true"/>
+        </subsystem>
+        <subsystem xmlns="urn:wildfly:elytron:7.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
+            <providers>
+                <aggregate-providers name="combined-providers">
+                    <providers name="elytron"/>
+                    <providers name="openssl"/>
+                </aggregate-providers>
+                <provider-loader name="elytron" module="org.wildfly.security.elytron"/>
+                <provider-loader name="openssl" module="org.wildfly.openssl"/>
+            </providers>
+            <audit-logging>
+                <file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
+            </audit-logging>
+            <security-domains>
+                <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
+                    <realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
+                    <realm name="local"/>
+                </security-domain>
+                <security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
+                    <realm name="ManagementRealm" role-decoder="groups-to-roles"/>
+                    <realm name="local" role-mapper="super-user-mapper"/>
+                </security-domain>
+            </security-domains>
+            <security-realms>
+                <identity-realm name="local" identity="$local"/>
+                <properties-realm name="ApplicationRealm">
+                    <users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
+                    <groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+                </properties-realm>
+                <properties-realm name="ManagementRealm">
+                    <users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
+                    <groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+                </properties-realm>
+            </security-realms>
+            <mappers>
+                <simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
+                    <permission-mapping>
+                        <principal name="anonymous"/>
+                        <permission-set name="default-permissions"/>
+                    </permission-mapping>
+                    <permission-mapping match-all="true">
+                        <permission-set name="login-permission"/>
+                        <permission-set name="default-permissions"/>
+                    </permission-mapping>
+                </simple-permission-mapper>
+                <constant-realm-mapper name="local" realm-name="local"/>
+                <simple-role-decoder name="groups-to-roles" attribute="groups"/>
+                <constant-role-mapper name="super-user-mapper">
+                    <role name="SuperUser"/>
+                </constant-role-mapper>
+            </mappers>
+            <permission-sets>
+                <permission-set name="login-permission">
+                    <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
+                </permission-set>
+                <permission-set name="default-permissions">
+                    <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+                    <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+                    <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+                </permission-set>
+            </permission-sets>
+            <http>
+                <http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global">
+                    <mechanism-configuration>
+                        <mechanism mechanism-name="DIGEST">
+                            <mechanism-realm realm-name="ManagementRealm"/>
+                        </mechanism>
+                    </mechanism-configuration>
+                </http-authentication-factory>
+                <provider-http-server-mechanism-factory name="global"/>
+            </http>
+            <sasl>
+                <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
+                    <mechanism-configuration>
+                        <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+                        <mechanism mechanism-name="DIGEST-MD5">
+                            <mechanism-realm realm-name="ApplicationRealm"/>
+                        </mechanism>
+                    </mechanism-configuration>
+                </sasl-authentication-factory>
+                <sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
+                    <mechanism-configuration>
+                        <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+                        <mechanism mechanism-name="DIGEST-MD5">
+                            <mechanism-realm realm-name="ManagementRealm"/>
+                        </mechanism>
+                    </mechanism-configuration>
+                </sasl-authentication-factory>
+                <configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
+                    <properties>
+                        <property name="wildfly.sasl.local-user.default-user" value="$local"/>
+                    </properties>
+                </configurable-sasl-server-factory>
+                <mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
+                    <filters>
+                        <filter provider-name="WildFlyElytron"/>
+                    </filters>
+                </mechanism-provider-filtering-sasl-server-factory>
+                <provider-sasl-server-factory name="global"/>
+            </sasl>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:infinispan:8.0">
+            <cache-container name="keycloak">
+                <local-cache name="realms">
+                    <object-memory size="10000"/>
+                </local-cache>
+                <local-cache name="users">
+                    <object-memory size="10000"/>
+                </local-cache>
+                <local-cache name="sessions"/>
+                <local-cache name="authenticationSessions"/>
+                <local-cache name="offlineSessions"/>
+                <local-cache name="clientSessions"/>
+                <local-cache name="offlineClientSessions"/>
+                <local-cache name="loginFailures"/>
+                <local-cache name="work"/>
+                <local-cache name="authorization">
+                    <object-memory size="10000"/>
+                </local-cache>
+                <local-cache name="keys">
+                    <object-memory size="1000"/>
+                    <expiration max-idle="3600000"/>
+                </local-cache>
+                <local-cache name="actionTokens">
+                    <object-memory size="-1"/>
+                    <expiration interval="300000" max-idle="-1"/>
+                </local-cache>
+            </cache-container>
+            <cache-container name="server" default-cache="default" module="org.wildfly.clustering.server">
+                <local-cache name="default">
+                    <transaction mode="BATCH"/>
+                </local-cache>
+            </cache-container>
+            <cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan">
+                <local-cache name="passivation">
+                    <locking isolation="REPEATABLE_READ"/>
+                    <transaction mode="BATCH"/>
+                    <file-store passivation="true" purge="false"/>
+                </local-cache>
+                <local-cache name="sso">
+                    <locking isolation="REPEATABLE_READ"/>
+                    <transaction mode="BATCH"/>
+                </local-cache>
+                <local-cache name="routing"/>
+            </cache-container>
+            <cache-container name="ejb" aliases="sfsb" default-cache="passivation" module="org.wildfly.clustering.ejb.infinispan">
+                <local-cache name="passivation">
+                    <locking isolation="REPEATABLE_READ"/>
+                    <transaction mode="BATCH"/>
+                    <file-store passivation="true" purge="false"/>
+                </local-cache>
+            </cache-container>
+            <cache-container name="hibernate" module="org.infinispan.hibernate-cache">
+                <local-cache name="entity">
+                    <object-memory size="10000"/>
+                    <expiration max-idle="100000"/>
+                </local-cache>
+                <local-cache name="local-query">
+                    <object-memory size="10000"/>
+                    <expiration max-idle="100000"/>
+                </local-cache>
+                <local-cache name="timestamps"/>
+            </cache-container>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:io:3.0">
+            <worker name="default"/>
+            <buffer-pool name="default"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
+        <subsystem xmlns="urn:jboss:domain:jca:5.0">
+            <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
+            <bean-validation enabled="true"/>
+            <default-workmanager>
+                <short-running-threads>
+                    <core-threads count="50"/>
+                    <queue-length count="50"/>
+                    <max-threads count="50"/>
+                    <keepalive-time time="10" unit="seconds"/>
+                </short-running-threads>
+                <long-running-threads>
+                    <core-threads count="50"/>
+                    <queue-length count="50"/>
+                    <max-threads count="50"/>
+                    <keepalive-time time="10" unit="seconds"/>
+                </long-running-threads>
+            </default-workmanager>
+            <cached-connection-manager/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:jmx:1.3">
+            <expose-resolved-model/>
+            <expose-expression-model/>
+            <remoting-connector/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:jpa:1.1">
+            <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+            <web-context>auth</web-context>
+            <providers>
+                <provider>
+                    classpath:${jboss.home.dir}/providers/*
+                </provider>
+            </providers>
+            <master-realm-name>master</master-realm-name>
+            <scheduled-task-interval>900</scheduled-task-interval>
+            <theme>
+                <staticMaxAge>-1</staticMaxAge>
+                <cacheThemes>false</cacheThemes>
+                <cacheTemplates>false</cacheTemplates>
+                <welcomeTheme>${env.KEYCLOAK_WELCOME_THEME:keycloak}</welcomeTheme>
+                <default>${env.KEYCLOAK_DEFAULT_THEME:keycloak}</default>
+                <dir>${jboss.home.dir}/themes</dir>
+            </theme>
+            <spi name="eventsStore">
+                <provider name="jpa" enabled="true">
+                    <properties>
+                        <property name="exclude-events" value="[&quot;REFRESH_TOKEN&quot;]"/>
+                    </properties>
+                </provider>
+            </spi>
+            <spi name="userCache">
+                <provider name="default" enabled="true"/>
+            </spi>
+            <spi name="userSessionPersister">
+                <default-provider>jpa</default-provider>
+            </spi>
+            <spi name="timer">
+                <default-provider>basic</default-provider>
+            </spi>
+            <spi name="connectionsHttpClient">
+                <provider name="default" enabled="true"/>
+            </spi>
+            <spi name="connectionsJpa">
+                <provider name="default" enabled="true">
+                    <properties>
+                        <property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
+                        <property name="initializeEmpty" value="true"/>
+                        <property name="migrationStrategy" value="update"/>
+                        <property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
+                    </properties>
+                </provider>
+            </spi>
+            <spi name="realmCache">
+                <provider name="default" enabled="true"/>
+            </spi>
+            <spi name="connectionsInfinispan">
+                <default-provider>default</default-provider>
+                <provider name="default" enabled="true">
+                    <properties>
+                        <property name="cacheContainer" value="java:jboss/infinispan/container/keycloak"/>
+                    </properties>
+                </provider>
+            </spi>
+            <spi name="jta-lookup">
+                <default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
+                <provider name="jboss" enabled="true"/>
+            </spi>
+            <spi name="publicKeyStorage">
+                <provider name="infinispan" enabled="true">
+                    <properties>
+                        <property name="minTimeBetweenRequests" value="10"/>
+                    </properties>
+                </provider>
+            </spi>
+            <spi name="x509cert-lookup">
+                <default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
+                <provider name="default" enabled="true"/>
+            </spi>
+            <spi name="hostname">
+                <default-provider>${keycloak.hostname.provider:request}</default-provider>
+                <provider name="fixed" enabled="true">
+                    <properties>
+                        <property name="hostname" value="${keycloak.hostname.fixed.hostname:localhost}"/>
+                        <property name="httpPort" value="${keycloak.hostname.fixed.httpPort:-1}"/>
+                        <property name="httpsPort" value="${keycloak.hostname.fixed.httpsPort:-1}"/>
+                        <property name="alwaysHttps" value="${keycloak.hostname.fixed.alwaysHttps:false}"/>
+                    </properties>
+                </provider>
+            </spi>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:mail:3.0">
+            <mail-session name="default" jndi-name="java:jboss/mail/Default">
+                <smtp-server outbound-socket-binding-ref="mail-smtp"/>
+            </mail-session>
+        </subsystem>
+        <subsystem xmlns="urn:wildfly:microprofile-config-smallrye:1.0"/>
+        <subsystem xmlns="urn:wildfly:microprofile-health-smallrye:1.0" security-enabled="false"/>
+        <subsystem xmlns="urn:wildfly:microprofile-metrics-smallrye:2.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:wildfly}"/>
+        <subsystem xmlns="urn:jboss:domain:naming:2.0">
+            <remote-naming/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:remoting:4.0">
+            <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
+        <subsystem xmlns="urn:jboss:domain:security:2.0">
+            <security-domains>
+                <security-domain name="other" cache-type="default">
+                    <authentication>
+                        <login-module code="Remoting" flag="optional">
+                            <module-option name="password-stacking" value="useFirstPass"/>
+                        </login-module>
+                        <login-module code="RealmDirect" flag="required">
+                            <module-option name="password-stacking" value="useFirstPass"/>
+                        </login-module>
+                    </authentication>
+                </security-domain>
+                <security-domain name="jboss-web-policy" cache-type="default">
+                    <authorization>
+                        <policy-module code="Delegating" flag="required"/>
+                    </authorization>
+                </security-domain>
+                <security-domain name="jaspitest" cache-type="default">
+                    <authentication-jaspi>
+                        <login-module-stack name="dummy">
+                            <login-module code="Dummy" flag="optional"/>
+                        </login-module-stack>
+                        <auth-module code="Dummy"/>
+                    </authentication-jaspi>
+                </security-domain>
+                <security-domain name="jboss-ejb-policy" cache-type="default">
+                    <authorization>
+                        <policy-module code="Delegating" flag="required"/>
+                    </authorization>
+                </security-domain>
+            </security-domains>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:security-manager:1.0">
+            <deployment-permissions>
+                <maximum-set>
+                    <permission class="java.security.AllPermission"/>
+                </maximum-set>
+            </deployment-permissions>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:transactions:5.0">
+            <core-environment node-identifier="${jboss.tx.node.id:1}">
+                <process-id>
+                    <uuid/>
+                </process-id>
+            </core-environment>
+            <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
+            <coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
+            <object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:undertow:9.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
+            <buffer-cache name="default"/>
+            <server name="default-server">
+                <http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="${env.PROXY_ADDRESS_FORWARDING:false}" enable-http2="true"/>
+                <https-listener name="https" socket-binding="https" proxy-address-forwarding="${env.PROXY_ADDRESS_FORWARDING:false}" security-realm="ApplicationRealm" enable-http2="true"/>
+                <host name="default-host" alias="localhost">
+                    <location name="/" handler="welcome-content"/>
+                    <http-invoker security-realm="ApplicationRealm"/>
+                </host>
+            </server>
+            <servlet-container name="default">
+                <jsp-config/>
+                <websockets/>
+            </servlet-container>
+            <handlers>
+                <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
+            </handlers>
+        </subsystem>
+        <subsystem xmlns="urn:jboss:domain:weld:4.0"/>
+    </profile>
+    <interfaces>
+        <interface name="management">
+            <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
+        </interface>
+        <interface name="public">
+            <inet-address value="${jboss.bind.address:127.0.0.1}"/>
+        </interface>
+    </interfaces>
+    <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
+        <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
+        <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
+        <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
+        <socket-binding name="http" port="${jboss.http.port:8080}"/>
+        <socket-binding name="https" port="${jboss.https.port:8443}"/>
+        <socket-binding name="txn-recovery-environment" port="4712"/>
+        <socket-binding name="txn-status-manager" port="4713"/>
+        <outbound-socket-binding name="mail-smtp">
+            <remote-destination host="localhost" port="25"/>
+        </outbound-socket-binding>
+    </socket-binding-group>
+</server>
\ No newline at end of file
diff --git a/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/error.ftl b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/error.ftl
new file mode 100644
index 0000000..8716dc8
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/error.ftl
@@ -0,0 +1,44 @@
+<#import "template.ftl" as layout>
+<@layout.registrationLayout displayInfo=true; section>
+    <#if section = "header">
+    <#elseif section = "form">
+        <style>
+            #kc-error {
+                position: relative;
+                z-index: 1;
+                background: #ffffff;
+                max-width: 460px;
+                margin: 0 auto 10px;
+                padding: 45px;
+                border-radius: 2px;
+                box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
+                color: red;
+            }
+
+            #kc-error-header > p {
+                font-weight: bold;
+                font-size: 1.4rem;
+                border-bottom: #dddddd 1px solid;
+                padding-bottom: 5px;
+            }
+        </style>
+        <div id="kc-error">
+            <div id="kc-error-header">
+                <p>
+                    We are sorry...
+                </p>
+            </div>
+            <div id="kc-error-message">
+                <#if message.summary?contains("Account is disabled")>
+                    <p class="instruction">Your account is locked. Please contact <a href="mailto:htrc-help@hathitrust.org">htrc-help@hathitrust.org</a>.</p>
+                <#else>
+                    <p class="instruction">${message.summary}</p>
+                </#if>
+                <#if client?? && client.baseUrl?has_content>
+                    <p><a id="backToApplication"
+                          href="${client.baseUrl}">Back to HTRC Analytics</a></p>
+                </#if>
+            </div>
+        </div>
+    </#if>
+</@layout.registrationLayout>
\ No newline at end of file
diff --git a/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/login-page-expired.ftl b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/login-page-expired.ftl
new file mode 100644
index 0000000..8d361c5
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/login-page-expired.ftl
@@ -0,0 +1,42 @@
+<#import "template.ftl" as layout>
+<@layout.registrationLayout; section>
+    <#if section = "header">
+    <#elseif section = "form">
+        <style>
+            #kc-instruction {
+                position: relative;
+                z-index: 1;
+                background: #ffffff;
+                max-width: 460px;
+                margin: 0 auto 10px;
+                padding: 45px;
+                border-radius: 2px;
+                box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
+                color: red;
+            }
+
+            #kc-instruction-header > p {
+                font-weight: bold;
+                font-size: 1.4rem;
+                border-bottom: #dddddd 1px solid;
+                padding-bottom: 5px;
+            }
+        </style>
+        <div id="kc-instruction">
+            <div id="kc-instruction-header">
+                <p>
+                    Page has expired
+                </p>
+            </div>
+            <div id="kc-instruction-message">
+                <p><a id="backToApplication"
+                      href="${client.baseUrl}">${kcSanitize(msg("backToApplication"))?no_esc}</a></p>
+<#--                <ul>-->
+<#--                    <li>To restart the login process <a id="loginRestartLink" href="${url.loginRestartFlowUrl}">Click here</a> .</li>-->
+<#--                    <li>To continue the login process <a id="loginContinueLink" href="${url.loginAction}">Click here</a> .</li>-->
+<#--                </ul>-->
+            </div>
+        </div>
+
+    </#if>
+</@layout.registrationLayout>
diff --git a/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/login.ftl b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/login.ftl
new file mode 100644
index 0000000..0e97d4e
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/login.ftl
@@ -0,0 +1,67 @@
+<#import "template.ftl" as layout>
+<@layout.registrationLayout displayInfo=social.displayInfo; section>
+    <#if section = "title">
+        Welcome to HTRC!
+    <#elseif section = "header">
+        <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
+        <link href="${url.resourcesPath}/img/favicon.png" rel="icon"/>
+        <script>
+            function togglePassword() {
+                var x = document.getElementById("password");
+                var v = document.getElementById("vi");
+                if (x.type === "password") {
+                    x.type = "text";
+                    v.src = "${url.resourcesPath}/img/eye.png";
+                } else {
+                    x.type = "password";
+                    v.src = "${url.resourcesPath}/img/eye-off.png";
+                }
+            }
+        </script>
+        <div class="welcome">
+            <div class="welcome-text">
+                <p>Welcome!</p>
+            </div>
+        </div>
+    <#elseif section = "form">
+        <div class="login">
+        <#if realm.password>
+            <div class="login-form">
+                <h3>Sign in to <span class="htrc-text">HathiTrust Research Center</span></h3>
+                <#if message?has_content>
+                    <div class="alert alert-${message.type}">
+                        <#if message.type = 'success'><span class="${properties.kcFeedbackSuccessIcon!}"></span></#if>
+                        <#if message.type = 'warning'><span class="${properties.kcFeedbackWarningIcon!}"></span></#if>
+                        <#if message.type = 'error'><span class="${properties.kcFeedbackErrorIcon!}"></span></#if>
+                        <#if message.type = 'info'><span class="${properties.kcFeedbackInfoIcon!}"></span></#if>
+                        <#if message.summary?contains("Account is disabled")>
+                            <span class="message-text">Your account is locked.<br/>Please contact <a href="mailto:htrc-help@hathitrust.org">htrc-help@hathitrust.org</a>.</span>
+                        <#else>
+                            <span class="message-text">${message.summary?no_esc}</span>
+                        </#if>
+                    </div>
+                </#if>
+               <form id="kc-form-login" class="form" onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">
+                <input id="username" class="login-field" placeholder="User name" type="text" name="username" tabindex="1">
+                <input id="password" class="login-field" placeholder="Password" type="password" name="password" tabindex="2">
+                <button type="submit" tabindex="3">Sign In</button>
+                </form>
+                <div class="link-group">
+                    <a id="passwordRecoverLink" href="${client.baseUrl}\passwordresetrequestpage">Forgot Password?</a> | <a id="usernameRecoverLink" href="${client.baseUrl}\useridrequestpage">Forgot Username?</a> | <a id="userSignUpLink" href="${client.baseUrl}\signuppage">Create Account</a>
+                </div>
+            </div>
+        </#if>
+        <#if social.providers??>
+            <p class="para">${msg("selectAlternative")}</p>
+            <div id="social-providers">
+                <#list social.providers as p>
+                <input class="social-link-style" type="button" onclick="location.href='${p.loginUrl}';" value="${p.displayName}"/>
+                </#list>
+            </div>
+        </#if>
+        <div class="login-footer">
+            <p>HathiTrust Research Center | © <script>document.write(new Date().getFullYear());</script></p>
+        </div>
+        </div>
+    </#if>
+</@layout.registrationLayout>
diff --git a/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/resources/css/styles.css b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/resources/css/styles.css
new file mode 100644
index 0000000..a5b4d70
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/resources/css/styles.css
@@ -0,0 +1,150 @@
+body,
+html {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
+  overflow: hidden;
+  min-height: 0;
+  font-size: 14px;
+  margin: 0;
+  height: 100%;
+}
+
+body {
+  background: #ff6f01;
+  background: -webkit-linear-gradient(bottom, #ff6f01, #ffb688);
+  background: -moz-linear-gradient(bottom, #ff6f01, #ffb688);
+  background: -o-linear-gradient(bottom, #ff6f01, #ffb688);
+  background: linear-gradient(to top, #ff6f01, #ffb688);
+  font-family: "Roboto", sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.htrc-text {
+  color: #ff6f01;
+}
+
+a {
+  color: #ff6f01;
+}
+
+a:hover,
+a:active,
+a:focus {
+  color: #ffb688;
+}
+
+.alert {
+    padding-top: 8px;
+    padding-bottom: 8px;
+}
+
+.alert-error {
+    color: red;
+}
+
+.welcome {
+  width: 460px;
+  margin: 0 auto;
+  padding-top: 5%;
+}
+
+.welcome-text {
+  padding-left: 45px;
+  padding-right: 45px;
+  padding-top: 8px;
+  padding-bottom: 8px;
+  background: white;
+  border-radius: 2px;
+  box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
+  color: #dc7729;
+  font-size: 16px;
+}
+
+
+.welcome-text > p {
+  line-height: 24px;
+  text-align: center;
+}
+
+.login-content {
+  padding: 2% 0 0;
+}
+.login {
+  width: 460px;
+  padding: 0 0;
+  margin: auto;
+}
+
+.login-form {
+  position: relative;
+  z-index: 1;
+  background: #ffffff;
+  max-width: 460px;
+  margin: 0 auto 10px;
+  padding: 45px;
+  border-radius: 2px;
+  box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
+}
+
+.login-form > h3 {
+  margin-bottom: 15px;
+  margin-top: 0;
+  padding-bottom: 5px;
+  border-bottom: 1px solid #ddd;
+  font-size: 16px;
+  font-family: "Roboto", sans-serif;
+  font-weight: 300;
+  color: #333;
+}
+
+.login-footer {
+  text-align: center;
+  font-family: "Roboto", sans-serif;
+  font-size: 13px;
+  width: 360px;
+  padding: 0px;
+  margin: auto;
+  color: #fff;
+}
+
+.login-form > form > input {
+  font-family: "Roboto", sans-serif;
+  outline: 0;
+  background: #f2f2f2;
+  width: 100%;
+  border: 0;
+  margin: 0 0 15px;
+  padding: 15px;
+  box-sizing: border-box;
+  font-size: 14px;
+}
+
+.login-form > form > button {
+  font-family: "Roboto", sans-serif;
+  text-transform: uppercase;
+  outline: 0;
+  background: #ff6f01;
+  width: 100%;
+  border: 0;
+  margin: 0 0 15px;
+  padding: 15px;
+  color: #ffffff;
+  font-size: 14px;
+  box-sizing: border-box;
+  -webkit-transition: all 0.3 ease;
+  transition: all 0.3 ease;
+  cursor: pointer;
+}
+
+.login-form > form > button:hover,
+.login-form > form > button:active,
+.login-form > form > button:focus {
+  background: #ffb688;
+}
+
+.link-group {
+  font-size: 14px;
+  text-align: center;
+}
diff --git a/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/template.ftl b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/template.ftl
new file mode 100644
index 0000000..8cfff69
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/template.ftl
@@ -0,0 +1,25 @@
+<#macro registrationLayout bodyClass="" displayInfo=false>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta name="robots" content="noindex, nofollow">
+
+    <title>Sign in to HathiTrust Research Center</title>
+    <#if properties.styles?has_content>
+        <#list properties.styles?split(' ') as style>
+            <link href="${url.resourcesPath}/${style}" rel="stylesheet" />
+        </#list>
+    </#if>
+</head>
+
+	<body>
+                <#nested "header">
+        <div class="login-content">
+                <#nested "form">
+        </div>
+	</body>
+</html>
+</#macro>
\ No newline at end of file
diff --git a/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/theme.properties b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/theme.properties
new file mode 100644
index 0000000..90e2de5
--- /dev/null
+++ b/custos-external-services-distributions/custos-keycloak/src/main/resources/themes/htrc/login/theme.properties
@@ -0,0 +1,20 @@
+#
+# Copyright 2016 Red Hat, Inc. and/or its affiliates
+# and other contributors as indicated by the @author tags.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+parent=keycloak
+styles=css/styles.css
+header=Welcome
\ No newline at end of file
diff --git a/custos-external-services-distributions/pom.xml b/custos-external-services-distributions/pom.xml
new file mode 100644
index 0000000..9b6afdd
--- /dev/null
+++ b/custos-external-services-distributions/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-external-services-distributions</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>custos-keycloak</module>
+        <module>custos-grpc-web-proxy</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-federated-services-clients/pom.xml b/custos-federated-services-clients/pom.xml
new file mode 100644
index 0000000..9f415cc
--- /dev/null
+++ b/custos-federated-services-clients/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-federated-services-clients</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>custos-core-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-admin-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-authz-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jackson2-provider</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jaxrs</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-multipart-provider</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20090211</version>
+        </dependency>
+    </dependencies>
+    <build>
+    <plugins>
+        <plugin>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-maven-plugin</artifactId>
+            <configuration>
+                <skip>true</skip>
+            </configuration>
+        </plugin>
+    </plugins>
+
+</build>
+
+</project>
\ No newline at end of file
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonClient.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonClient.java
new file mode 100644
index 0000000..53debf3
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonClient.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.cilogon;
+
+import org.json.JSONException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.*;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import javax.validation.constraints.NotNull;
+import java.util.Base64;
+
+/**
+ * This class is responsible for CILogon operations
+ */
+@Component
+public class CILogonClient {
+    private final static Logger LOGGER = LoggerFactory.getLogger(CILogonClient.class);
+
+    @Value("${ciLogon.admin.client.id}")
+    private String adminClientId;
+
+
+    @Value("${ciLogon.admin.client.secret}")
+    private String adminClientSecret;
+
+
+    @Value("${ciLogon.admin.auth.endpoint:https://test.cilogon.org/oauth2/oidc-cm}")
+    private String ciLogonAuthEndpoint;
+
+    @Value("${ciLogon.institutions.endpoint:https://cilogon.org/idplist/}")
+    private String ciLogonInstitutionsEndpoint;
+
+    private RestTemplate template = new RestTemplate();
+
+
+    public CILogonResponse registerClient(@NotNull String clientName, @NotNull String[] redirectURIs,
+                                          @NotNull String comment, String[] scopes, String homeURL,
+                                          String contactEmail) throws JSONException {
+
+        CILogonRequest req = new CILogonRequest();
+
+        req.setClientName(clientName);
+        req.setRedirectURIs(redirectURIs);
+        req.setComment(comment);
+
+        if (scopes != null && scopes.length > 0) {
+            req.setScope(scopes);
+        }
+
+        if (homeURL != null) {
+            req.setClientURI(homeURL);
+        }
+
+        if (contactEmail != null) {
+            req.setContacts(new String[]{contactEmail});
+        }
+        HttpHeaders headers = new HttpHeaders();
+
+
+        headers.add("Authorization", getBearerToken());
+        headers.setContentType(MediaType.APPLICATION_JSON);
+
+
+        HttpEntity<CILogonRequest> entity = new HttpEntity<CILogonRequest>(req, headers);
+        ResponseEntity<CILogonResponse> responseEntity = template.exchange
+                (ciLogonAuthEndpoint, HttpMethod.POST, entity, CILogonResponse.class);
+        return responseEntity.getBody();
+    }
+
+    public CILogonResponse getClient(@NotNull String clientId) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Authorization", getBearerToken());
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity entity = new HttpEntity(headers);
+
+        String url = ciLogonAuthEndpoint + "?client_id=" + clientId;
+        System.out.println(url);
+        ResponseEntity<CILogonResponse> responseEntity = template.
+                exchange(url, HttpMethod.GET, entity, CILogonResponse.class);
+
+        return responseEntity.getBody();
+    }
+
+    public void updateClient(@NotNull String clientId, @NotNull String clientName,
+                             @NotNull String[] redirectURIs, @NotNull String comment, String[] scopes,
+                             String homeURL, String contactEmail) {
+        CILogonRequest req = new CILogonRequest();
+
+        req.setClientName(clientName);
+        req.setRedirectURIs(redirectURIs);
+        req.setComment(comment);
+
+        if (scopes != null && scopes.length > 0) {
+            req.setScope(scopes);
+        }
+
+        if (homeURL != null) {
+            req.setClientURI(homeURL);
+        }
+
+        if (contactEmail != null) {
+            req.setContacts(new String[]{contactEmail});
+        }
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Authorization", getBearerToken());
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<CILogonRequest> entity = new HttpEntity<CILogonRequest>(req, headers);
+        String url = ciLogonAuthEndpoint + "?client_id=" + clientId;
+        template.put(url, entity);
+    }
+
+
+    public void deleteClient(@NotNull String clientId) {
+
+        String url = ciLogonAuthEndpoint + "?client_id=" + clientId;
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Authorization", getBearerToken());
+        HttpEntity<Object> entity = new HttpEntity<Object>(headers);
+        template.exchange(url, HttpMethod.DELETE, entity, String.class);
+    }
+
+
+    public CILogonInstitution[] getInstitutions() {
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Authorization", getBearerToken());
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity entity = new HttpEntity(headers);
+
+        String url = ciLogonInstitutionsEndpoint;
+
+        ResponseEntity<CILogonInstitution[]> responseEntity = template.
+                exchange(url, HttpMethod.GET, entity, CILogonInstitution[].class);
+
+        return responseEntity.getBody();
+
+    }
+
+
+    private String getBearerToken() {
+        String decoded = adminClientId + ":" + adminClientSecret;
+        return "Bearer " + Base64.getEncoder().encodeToString(decoded.getBytes());
+    }
+
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonInstitution.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonInstitution.java
new file mode 100644
index 0000000..2224457
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonInstitution.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.cilogon;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class CILogonInstitution {
+
+    @JsonProperty(value = "EntityID")
+    private String entityId;
+
+    @JsonProperty(value = "OrganizationName")
+    private String organizationName;
+
+    @JsonProperty(value = "DisplayName")
+    private String displayName;
+
+    @JsonProperty(value = "RandS")
+    private boolean randS;
+
+
+    public String getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(String entityId) {
+        this.entityId = entityId;
+    }
+
+    public String getOrganizationName() {
+        return organizationName;
+    }
+
+    public void setOrganizationName(String organizationName) {
+        this.organizationName = organizationName;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    public boolean isRandS() {
+        return randS;
+    }
+
+    public void setRandS(boolean randS) {
+        this.randS = randS;
+    }
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonRequest.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonRequest.java
new file mode 100644
index 0000000..022792d
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonRequest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.cilogon;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CILogonRequest {
+
+
+    @JsonProperty(value = "client_name")
+    private String clientName ;
+
+    @JsonProperty(value = "redirect_uris")
+    private String[] redirectURIs = new String[0];
+
+
+    @JsonProperty(value = "comment")
+    private String comment;
+
+    @JsonProperty(value = "scope")
+    private String[] scope = new String[0];
+
+    @JsonProperty(value = "client_uri")
+    private String clientURI;
+
+    @JsonProperty(value = "contacts")
+    private String[] contacts = new String[0];
+
+
+
+    public String getClientName() {
+        return clientName;
+    }
+
+    public void setClientName(String clientName) {
+        this.clientName = clientName;
+    }
+
+    public String[] getRedirectURIs() {
+        return redirectURIs;
+    }
+
+    public void setRedirectURIs(String[] redirectURIs) {
+        this.redirectURIs = redirectURIs;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public String[] getScope() {
+        return scope;
+    }
+
+    public void setScope(String[] scopes) {
+        this.scope = scopes;
+    }
+
+    public String getClientURI() {
+        return clientURI;
+    }
+
+    public void setClientURI(String clientURI) {
+        this.clientURI = clientURI;
+    }
+
+    public String[] getContacts() {
+        return contacts;
+    }
+
+    public void setContacts(String[] contacts) {
+        this.contacts = contacts;
+    }
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonResponse.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonResponse.java
new file mode 100644
index 0000000..c77af12
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/cilogon/CILogonResponse.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.cilogon;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CILogonResponse {
+
+    @JsonProperty(value = "client_id")
+    private String clientId;
+
+    @JsonProperty(value = "client_secret")
+    private String clientSecret;
+
+
+    @JsonProperty(value = "client_secret_expired_at")
+    private long clientSecretExpiredAt;
+
+    @JsonProperty(value = "registration_client_uri")
+    private String registrationClientURI;
+
+    @JsonProperty(value = "client_name")
+    private String clientName ;
+
+    @JsonProperty(value = "redirect_uris")
+    private String[] redirectURIs = new String[0];
+
+    @JsonProperty(value = "scope")
+    private String[] scope = new String[0];
+
+    @JsonProperty(value = "grant_types")
+    private String[] grantTypes;
+
+    @JsonProperty(value = "comment")
+    private String comment;
+
+    @JsonProperty(value = "client_id_issued_at")
+    private long clientIdIssuedAt;
+
+    @JsonProperty(value = "contacts")
+    private String[] contacts = new String[0];
+
+    @JsonProperty(value = "client_uri")
+    private String clientURI;
+
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public String getClientSecret() {
+        return clientSecret;
+    }
+
+    public void setClientSecret(String clientSecret) {
+        this.clientSecret = clientSecret;
+    }
+
+
+
+    public long getClientSecretExpiredAt() {
+        return clientSecretExpiredAt;
+    }
+
+    public void setClientSecretExpiredAt(long clientSecretExpiredAt) {
+        this.clientSecretExpiredAt = clientSecretExpiredAt;
+    }
+
+    public String getRegistrationClientURI() {
+        return registrationClientURI;
+    }
+
+    public void setRegistrationClientURI(String registrationClientURI) {
+        this.registrationClientURI = registrationClientURI;
+    }
+
+    public String getClientName() {
+        return clientName;
+    }
+
+    public void setClientName(String clientName) {
+        this.clientName = clientName;
+    }
+
+    public String[] getRedirectURIs() {
+        return redirectURIs;
+    }
+
+    public void setRedirectURIs(String[] redirectURIs) {
+        this.redirectURIs = redirectURIs;
+    }
+
+    public String[] getScope() {
+        return scope;
+    }
+
+    public void setScope(String[] scope) {
+        this.scope = scope;
+    }
+
+    public String[] getGrantTypes() {
+        return grantTypes;
+    }
+
+    public void setGrantTypes(String[] grantTypes) {
+        this.grantTypes = grantTypes;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public long getClientIdIssuedAt() {
+        return clientIdIssuedAt;
+    }
+
+    public void setClientIdIssuedAt(long clientIdIssuedAt) {
+        this.clientIdIssuedAt = clientIdIssuedAt;
+    }
+
+    public String[] getContacts() {
+        return contacts;
+    }
+
+    public void setContacts(String[] contacts) {
+        this.contacts = contacts;
+    }
+
+    public String getClientURI() {
+        return clientURI;
+    }
+
+    public void setClientURI(String clientURI) {
+        this.clientURI = clientURI;
+    }
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClient.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClient.java
new file mode 100644
index 0000000..e127c5a
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClient.java
@@ -0,0 +1,1978 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.keycloak;
+
+import org.apache.catalina.security.SecurityUtil;
+import org.apache.custos.core.services.commons.util.Constants;
+import org.apache.http.HttpStatus;
+import org.jboss.resteasy.client.jaxrs.ResteasyClient;
+import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
+import org.keycloak.admin.client.Keycloak;
+import org.keycloak.admin.client.resource.*;
+import org.keycloak.representations.idm.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.core.Response;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.security.KeyStore;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * This class acts as a rest client for keycloak server
+ */
+@Component
+public class KeycloakClient {
+    private final static Logger LOGGER = LoggerFactory.getLogger(KeycloakClient.class);
+
+
+    private final static int POOL_SIZE = 10;
+
+    private final static int ACCESS_TOKEN_LIFE_SPAN = 1800;
+
+    private final static int SESSION_IDLE_TIMEOUT = 3600;
+
+    @Value("${iam.server.client.id:admin-cli}")
+    private String clientId;
+
+    @Value("${iam.server.truststore.path:/home/ubuntu/keystore/keycloak-client-truststore.pkcs12}")
+    private String trustStorePath;
+
+    @Value("${iam.server.truststore.password:keycloak}")
+    private String truststorePassword;
+
+    @Value("${iam.server.url:https://keycloak.custos.scigap.org:31000/auth/}")
+    private String iamServerURL;
+
+    @Value("${iam.server.admin.username}")
+    private String superAdminUserName;
+
+    @Value("${iam.server.admin.password}")
+    private String superAdminPassword;
+
+    @Value("${iam.server.super.admin.realm.id:master}")
+    private String superAdminRealmID;
+
+    @Value("${iam.federated.cilogon.authorization.endpoint:https://cilogon.org/authorize}")
+    private String ciLogonAuthorizationEndpoint;
+
+    @Value("${iam.federated.cilogon.token.endpoint:https://cilogon.org/oauth2/token}")
+    private String ciLogonTokenEndpoint;
+
+    @Value("${iam.federated.cilogon.token.userinfo.endpoint:https://cilogon.org/oauth2/userinfo}")
+    private String ciLogonUserInfoEndpoint;
+
+    @Value("${iam.federated.cilogon.issuer:https://cilogon.org}")
+    private String ciLogonIssuerUri;
+
+    @Value("${iam.federated.cilogon.jwksUri:https://cilogon.org/oauth2/certs}")
+    private String jwksUri;
+
+    public void createRealm(String realmId, String displayName) {
+        Keycloak client = null;
+        try {
+            // get client
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+            // create realm
+            RealmRepresentation newRealmDetails = new RealmRepresentation();
+            newRealmDetails.setEnabled(true);
+            newRealmDetails.setId(realmId);
+            newRealmDetails.setDisplayName(displayName);
+            newRealmDetails.setRealm(realmId);
+            // Following two settings allow duplicate email addresses
+            newRealmDetails.setLoginWithEmailAllowed(false);
+            newRealmDetails.setDuplicateEmailsAllowed(true);
+            // Default access token lifespan to 30 minutes, SSO session idle to 60 minutes
+            newRealmDetails.setAccessTokenLifespan(ACCESS_TOKEN_LIFE_SPAN);
+            newRealmDetails.setSsoSessionIdleTimeout(SESSION_IDLE_TIMEOUT);
+            RealmRepresentation realmWithRoles = createDefaultRoles(newRealmDetails);
+            client.realms().create(realmWithRoles);
+
+
+        } catch (Exception ex) {
+            String msg = "Error creating Realm in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public void updateRealm(String realmId, String displayName) {
+        Keycloak client = null;
+        try {
+            // get client
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+            // create realm
+
+            RealmResource realmResource = client.realm(realmId);
+
+            if (realmResource != null) {
+
+                RealmRepresentation newRealmDetails = realmResource.toRepresentation();
+                newRealmDetails.setId(realmId);
+                newRealmDetails.setDisplayName(displayName);
+                newRealmDetails.setRealm(realmId);
+                realmResource.update(newRealmDetails);
+            } else {
+                String msg = "Realm not found, reason: ";
+                LOGGER.error(msg);
+                throw new RuntimeException(msg, null);
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error creating Realm in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+    public boolean createRealmAdminAccount(String realmId, String adminUsername, String adminFirstname, String adminLastname, String adminEmail, String adminPassword) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+            UserRepresentation user = new UserRepresentation();
+            user.setUsername(adminUsername);
+            user.setFirstName(adminFirstname);
+            user.setLastName(adminLastname);
+            user.setEmail(adminEmail);
+            user.setEmailVerified(true);
+            user.setEnabled(true);
+            Response httpResponse = client.realm(realmId).users().create(user);
+            LOGGER.debug("Realm admin account creation exited with code : " + httpResponse.getStatus() + " : " + httpResponse.getStatusInfo());
+            if (httpResponse.getStatus() == HttpStatus.SC_CREATED) { //HTTP code for record creation: HTTP 201
+                List<UserRepresentation> retrieveCreatedUserList = client.realm(realmId).users().search(user.getUsername(),
+                        user.getFirstName(),
+                        user.getLastName(),
+                        user.getEmail(),
+                        0, 1);
+                UserResource retrievedUser = client.realm(realmId).users().get(retrieveCreatedUserList.get(0).getId());
+
+                // Add user to the "admin" role
+                RoleResource adminRoleResource = client.realm(realmId).roles().get("admin");
+                retrievedUser.roles().realmLevel().add(Arrays.asList(adminRoleResource.toRepresentation()));
+
+                CredentialRepresentation credential = new CredentialRepresentation();
+                credential.setType(CredentialRepresentation.PASSWORD);
+                credential.setValue(adminPassword);
+                credential.setTemporary(false);
+                retrievedUser.resetPassword(credential);
+                List<ClientRepresentation> realmClients = client.realm(realmId).clients().findAll();
+                String realmManagementClientId = getRealmManagementClientId(client, realmId);
+                for (ClientRepresentation realmClient : realmClients) {
+                    if (realmClient.getClientId().equals("realm-management")) {
+                        realmManagementClientId = realmClient.getId();
+                    }
+                }
+                retrievedUser.roles().clientLevel(realmManagementClientId).add(retrievedUser.roles().clientLevel(realmManagementClientId).listAvailable());
+                return true;
+            } else {
+                LOGGER.error("Request for Tenant Admin Account Creation failed with HTTP code : " + httpResponse.getStatus());
+                LOGGER.error("Reason for Tenant Admin account creation failure : " + httpResponse.getStatusInfo());
+                throw new RuntimeException("Reason for Tenant Admin account creation failure : " + httpResponse.getStatusInfo(), null);
+            }
+        } catch (Exception ex) {
+            String msg = "Error creating Realm Admin Account in keycloak server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean updateRealmAdminAccount(String realmId, String adminUsername, String adminFirstname, String adminLastname, String adminEmail, String adminPassword) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+            UserRepresentation representation = getUserByUsername(client, realmId, adminUsername);
+            if (representation != null) {
+                UserRepresentation user = representation;
+                user.setUsername(adminUsername);
+                user.setFirstName(adminFirstname);
+                user.setLastName(adminLastname);
+                user.setEmail(adminEmail);
+                user.setEmailVerified(true);
+                user.setEnabled(true);
+                client.realm(realmId).users().get(representation.getId()).update(representation);
+                return true;
+            } else {
+                return createRealmAdminAccount(realmId, adminUsername, adminFirstname, adminLastname, adminEmail, adminPassword);
+            }
+        } catch (Exception ex) {
+            String msg = "Error updating Realm Admin Account in keycloak server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean grantAdminPrivilege(String realmId, String username) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+            UserRepresentation representation = getUserByUsername(client, realmId, username);
+            if (representation != null) {
+
+                UserResource retrievedUser = client.realm(realmId).users().get(representation.getId());
+                RoleResource adminRoleResource = client.realm(realmId).roles().get("admin");
+                retrievedUser.roles().realmLevel().add(Arrays.asList(adminRoleResource.toRepresentation()));
+
+                String realmManagementClientId = getRealmManagementClientId(client, realmId);
+
+                retrievedUser.roles().clientLevel(realmManagementClientId).add(retrievedUser.roles().clientLevel(realmManagementClientId).listAvailable());
+                return true;
+
+            } else {
+                String msg = "Cannot find existing user with username " + username;
+                LOGGER.error(msg);
+                throw new RuntimeException(msg);
+            }
+        } catch (Exception ex) {
+            String msg = "Error granting admin privilege, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+    public boolean removeAdminPrivilege(String realmId, String username) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+            UserRepresentation representation = getUserByUsername(client, realmId, username);
+            if (representation != null) {
+
+                UserResource retrievedUser = client.realm(realmId).users().get(representation.getId());
+                RoleResource adminRoleResource = client.realm(realmId).roles().get("admin");
+                retrievedUser.roles().realmLevel().remove(Arrays.asList(adminRoleResource.toRepresentation()));
+                String realmManagementClientId = getRealmManagementClientId(client, realmId);
+                List<RoleRepresentation> representations = retrievedUser.roles().clientLevel(realmManagementClientId).listEffective();
+
+                retrievedUser.roles().clientLevel(realmManagementClientId).remove(retrievedUser.roles().clientLevel(realmManagementClientId).listEffective());
+                return true;
+
+            } else {
+                String msg = "Cannot find existing user with username " + username;
+                LOGGER.error(msg);
+                throw new RuntimeException(msg);
+            }
+        } catch (Exception ex) {
+            String msg = "Error removing admin privilege, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public KeycloakClientSecret configureClient(String realmId, String clientName, @NotNull String tenantURL, List<String> redirectUris) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+            ClientRepresentation pgaClient = new ClientRepresentation();
+            pgaClient.setName(clientName);
+            pgaClient.setClientId(clientName);
+            pgaClient.setProtocol("openid-connect");
+            pgaClient.setStandardFlowEnabled(true);
+            pgaClient.setEnabled(true);
+            pgaClient.setAuthorizationServicesEnabled(true);
+            pgaClient.setDirectAccessGrantsEnabled(true);
+            pgaClient.setServiceAccountsEnabled(true);
+            pgaClient.setFullScopeAllowed(true);
+            pgaClient.setClientAuthenticatorType("client-secret");
+
+
+            pgaClient.setBaseUrl(tenantURL);
+
+
+            // Remove trailing slash from gatewayURL
+            if (tenantURL.endsWith("/")) {
+                tenantURL = tenantURL.substring(0, tenantURL.length() - 1);
+            }
+            // Add redirect URL after login
+            // redirectUris.add(tenantURL + "/callback-url"); // PGA
+            // redirectUris.add(tenantURL + "/auth/callback*"); // Django
+            // Add redirect URL after logout
+
+            List<String> newList = new ArrayList<>();
+            newList.addAll(redirectUris);
+            newList.add(tenantURL);
+
+
+            pgaClient.setRedirectUris(newList);
+
+            List<String> webOrigins = new ArrayList<>();
+            webOrigins.add("+");
+            pgaClient.setWebOrigins(webOrigins);
+
+            pgaClient.setPublicClient(false);
+            Response httpResponse = client.realms().realm(realmId).clients().create(pgaClient);
+            LOGGER.debug("Realm client configuration exited with code : " + httpResponse.getStatus() + " : " + httpResponse.getStatusInfo());
+
+            // Add the manage-users role to the web client
+            UserRepresentation serviceAccountUserRepresentation = getUserByUsername(client, realmId, "service-account-" + pgaClient.getClientId());
+            UserResource serviceAccountUser = client.realms().realm(realmId).users().get(serviceAccountUserRepresentation.getId());
+            String realmManagementClientId = getRealmManagementClientId(client, realmId);
+            List<RoleRepresentation> manageUsersRole = serviceAccountUser.roles().clientLevel(realmManagementClientId).listAvailable()
+                    .stream()
+                    .filter(r -> r.getName().equals("manage-users"))
+                    .collect(Collectors.toList());
+            serviceAccountUser.roles().clientLevel(realmManagementClientId).add(manageUsersRole);
+
+            if (httpResponse.getStatus() == HttpStatus.SC_CREATED) {
+                String ClientUUID = client.realms().realm(realmId).clients().findByClientId(pgaClient.getClientId()).get(0).getId();
+                CredentialRepresentation clientSecret = client.realms().realm(realmId).clients().get(ClientUUID).getSecret();
+                KeycloakClientSecret keycloakClientSecret = new KeycloakClientSecret(pgaClient.getClientId(), clientSecret.getValue());
+                return keycloakClientSecret;
+            } else {
+                LOGGER.error("Request for realm client creation failed with HTTP code : " + httpResponse.getStatus());
+                LOGGER.error("Reason for realm client creation failure : " + httpResponse.getStatusInfo());
+                throw new RuntimeException("Reason for realm client creation failure :" + httpResponse.getStatusInfo(), null);
+            }
+        } catch (Exception ex) {
+            String msg = "Error getting values from property file, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public KeycloakClientSecret updateClient(String realmId, String clientName, @NotNull String tenantURL, List<String> redirectUris) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            List<ClientRepresentation> clientRepresentations = client.realm(realmId).clients().findByClientId(clientName);
+
+            if (clientRepresentations == null || clientRepresentations.isEmpty()) {
+                String msg = "Cannot find a client with name " + clientName;
+                LOGGER.error(msg);
+                throw new RuntimeException(msg);
+            }
+
+            ClientRepresentation pgaClient = clientRepresentations.get(0);
+
+            pgaClient.setBaseUrl(tenantURL);
+
+
+            // Remove trailing slash from gatewayURL
+            if (tenantURL.endsWith("/")) {
+                tenantURL = tenantURL.substring(0, tenantURL.length() - 1);
+            }
+            // Add redirect URL after login
+            // redirectUris.add(tenantURL + "/callback-url"); // PGA
+            // redirectUris.add(tenantURL + "/auth/callback*"); // Django
+            // Add redirect URL after logout
+
+            List<String> newList = new ArrayList<>();
+            newList.addAll(redirectUris);
+            newList.add(tenantURL);
+
+
+            pgaClient.setRedirectUris(newList);
+            pgaClient.setPublicClient(false);
+            client.realms().realm(realmId).clients().get(pgaClient.getId()).update(pgaClient);
+
+            String ClientUUID = client.realms().realm(realmId).clients().findByClientId(pgaClient.getClientId()).get(0).getId();
+            CredentialRepresentation clientSecret = client.realms().realm(realmId).clients().get(ClientUUID).getSecret();
+            KeycloakClientSecret keycloakClientSecret = new KeycloakClientSecret(pgaClient.getClientId(), clientSecret.getValue());
+            return keycloakClientSecret;
+
+        } catch (Exception ex) {
+            String msg = "Error getting values from property file, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean isUsernameAvailable(String realmId, String username, String accessToken) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+            return userRepresentation == null;
+        } catch (Exception ex) {
+            String msg = "Error getting values from property file, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean createUser(String realmId, String username, String newPassword, String firstName,
+                              String lastName, String emailAddress, boolean tempPassowrd, String accessToken) throws UnauthorizedException {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            UserRepresentation user = new UserRepresentation();
+            user.setUsername(username);
+            user.setFirstName(firstName);
+            user.setLastName(lastName);
+            user.setEmail(emailAddress);
+            user.setEnabled(false);
+            Response httpResponse = client.realm(realmId).users().create(user);
+
+            if (httpResponse.getStatus() == HttpStatus.SC_CREATED) { //HTTP code for record creation: HTTP 201
+                List<UserRepresentation> retrieveCreatedUserList = client.realm(realmId).users().search(user.getUsername(),
+                        user.getFirstName(),
+                        user.getLastName(),
+                        user.getEmail(),
+                        0, 1);
+                UserResource retrievedUser = client.realm(realmId).users().get(retrieveCreatedUserList.get(0).getId());
+                CredentialRepresentation credential = new CredentialRepresentation();
+                credential.setType(CredentialRepresentation.PASSWORD);
+                credential.setValue(newPassword);
+                credential.setTemporary(tempPassowrd);
+                retrievedUser.resetPassword(credential);
+                return true;
+            } else {
+                String msg = "Reason for user account creation failure : " + httpResponse.getStatusInfo();
+                LOGGER.error("Request for user Account Creation failed with HTTP code : " + httpResponse.getStatus());
+                LOGGER.error(msg);
+                throw new UnauthorizedException(msg, null);
+            }
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean enableUserAccount(String realmId, String accessToken, String username) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+
+            UserResource userResource = client.realm(realmId).users().get(userRepresentation.getId());
+            UserRepresentation profile = userResource.toRepresentation();
+            profile.setEnabled(true);
+            // We require that a user verify their email before enabling the account
+            // profile.setEmailVerified(true);
+            userResource.update(profile);
+            return true;
+        } catch (Exception ex) {
+            String msg = "Error occurred enableUserAccount, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean disableUserAccount(String realmId, String accessToken, String username) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+
+            if (userRepresentation != null) {
+
+                UserResource userResource = client.realm(realmId).users().get(userRepresentation.getId());
+                UserRepresentation profile = userResource.toRepresentation();
+                profile.setEnabled(false);
+                // We require that a user verify their email before enabling the account
+                // profile.setEmailVerified(true);
+                userResource.update(profile);
+            }
+            return true;
+        } catch (Exception ex) {
+            String msg = "Error in disableUserAccount at keycloak, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+    public boolean isUserAccountEnabled(String realmId, String accessToken, String username) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+            return userRepresentation != null && userRepresentation.isEnabled();
+        } catch (Exception ex) {
+            String msg = "Error getting values from property file, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+    public boolean isUserExist(String realmId, String accessToken, String username) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+            return userRepresentation != null;
+        } catch (Exception ex) {
+            String msg = "Error getting values from property file, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+    public UserRepresentation getUser(String realmId, String accessToken, String username) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            return getUserByUsername(client, realmId, username);
+        } catch (Exception ex) {
+            String msg = "Error retrieving user, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public List<UserRepresentation> getUsers(String accessToken, String realmId, int offset, int limit,
+                                             String username, String firstName, String lastName, String email, String search) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            return searchUsers(client, realmId, username, firstName, lastName, email, search, offset, limit);
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while searching for user, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean resetUserPassword(String accessToken, String realmId, String username, String newPassword) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+            if (userRepresentation != null) {
+                UserResource retrievedUser = client.realm(realmId).users().get(userRepresentation.getId());
+                CredentialRepresentation credential = new CredentialRepresentation();
+                credential.setType(CredentialRepresentation.PASSWORD);
+                credential.setValue(newPassword);
+                credential.setTemporary(false);
+                retrievedUser.resetPassword(credential);
+                // Remove the UPDATE_PASSWORD required action
+                userRepresentation = retrievedUser.toRepresentation();
+                userRepresentation.getRequiredActions().remove("UPDATE_PASSWORD");
+                retrievedUser.update(userRepresentation);
+                return true;
+            } else {
+                String msg = "requested User not found";
+                LOGGER.error(msg);
+                throw new RuntimeException(msg);
+            }
+        } catch (Exception ex) {
+            String msg = "Error resetting user password in keycloak server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public List<UserRepresentation> findUser(String accessToken, String realmId, String email, String userName) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            return client.realm(realmId).users().search(userName,
+                    null,
+                    null,
+                    email,
+                    0, 1);
+        } catch (Exception ex) {
+            String msg = "Error finding user in keycloak server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+    public void updateUserRepresentation(String accessToken, String realmId, String username,
+                                         String firstname, String lastName, String email) {
+
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+            if (userRepresentation != null) {
+                userRepresentation.setFirstName(firstname);
+                userRepresentation.setLastName(lastName);
+                userRepresentation.setEmail(email);
+                UserResource userResource = client.realm(realmId).users().get(userRepresentation.getId());
+
+                userResource.update(userRepresentation);
+            } else {
+                throw new RuntimeException("User [" + username + "] wasn't found in Keycloak!");
+            }
+        } catch (Exception ex) {
+            String msg = "Error updating user profile in keycloak server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean deleteUser(String accessToken, String realmId, String username) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+            if (userRepresentation != null) {
+                client.realm(realmId).users().delete(userRepresentation.getId());
+                return true;
+            } else {
+                throw new RuntimeException("User [" + username + "] wasn't found in Keycloak!");
+            }
+        } catch (Exception ex) {
+            String msg = "Error deleting user in keycloak server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean addRolesToUsers(String accessToken, String realmId, List<String> users, List<String> roles, String clientId, boolean clientLevel) {
+
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            for (String username : users) {
+
+                UserRepresentation representation = getUserByUsername(client, realmId, username.toLowerCase());
+                ClientRepresentation clientRepresentation = client.realm(realmId).clients().findByClientId(clientId).get(0);
+                if (representation != null) {
+                    RealmResource realmResource = client.realm(realmId);
+                    UserResource resource = client.realm(realmId).users().get(representation.getId());
+                    List<RoleRepresentation> roleRepresentations = new ArrayList<>();
+                    if (clientLevel) {
+                        for (String role : roles) {
+                            RoleResource roleResource = realmResource.clients().get(clientRepresentation.getId()).roles().get(role);
+                            roleRepresentations.add(roleResource.toRepresentation());
+                        }
+                        resource.roles().clientLevel(clientRepresentation.getId()).add(roleRepresentations);
+
+                    } else {
+
+                        for (String role : roles) {
+                            RoleResource roleResource = client.realm(realmId).roles().get(role);
+                            roleRepresentations.add(roleResource.toRepresentation());
+                        }
+                        resource.roles().realmLevel().add(roleRepresentations);
+                    }
+
+                }
+            }
+            return true;
+        } catch (Exception ex) {
+            String msg = "Error while adding roles to user " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean removeRoleFromUser(String accessToken, String realmId, String username, List<String> roles, String clientId, boolean clientLevel) {
+
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+            UserRepresentation representation = getUserByUsername(client, realmId, username.toLowerCase());
+
+            if (representation != null) {
+                UserResource retrievedUser = client.realm(realmId).users().get(representation.getId());
+
+                if (clientLevel) {
+                    List<ClientRepresentation> clientRepresentationList =
+                            client.realm(realmId).clients().findByClientId(clientId);
+
+                    if (clientRepresentationList != null && !clientRepresentationList.isEmpty()) {
+                        ClientRepresentation clientRep = clientRepresentationList.get(0);
+                        List<RoleRepresentation> roleRepresentations = new ArrayList<>();
+                        for (String roleName : roles) {
+                            RoleResource roleResource = client.realm(realmId).
+                                    clients().get(clientRep.getId()).roles().get(roleName);
+                            if (roleResource != null) {
+                                roleRepresentations.add(roleResource.toRepresentation());
+                            }
+                        }
+                        if (!roleRepresentations.isEmpty()) {
+                            retrievedUser.roles().clientLevel(clientRep.getId()).remove(roleRepresentations);
+                        }
+
+
+                    }
+                } else {
+                    List<RoleRepresentation> roleRepresentations = new ArrayList<>();
+                    for (String roleName : roles) {
+                        RoleResource roleResource = client.realm(realmId).roles().get(roleName);
+                        if (roleResource != null) {
+                            roleRepresentations.add(roleResource.toRepresentation());
+                        }
+                    }
+                    if (!roleRepresentations.isEmpty()) {
+                        retrievedUser.roles().realmLevel().remove(roleRepresentations);
+                    }
+                }
+            }
+            return true;
+        } catch (Exception ex) {
+            String msg = "Error removing roles from user , reason " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean deleteRealm(String realmId) {
+        Keycloak client = null;
+        try {
+            // get client
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            RealmResource realmResource = client.realm(realmId);
+
+            if (realmResource != null) {
+                realmResource.remove();
+            }
+
+        } catch (NotFoundException ex) {
+            LOGGER.debug("Realm not found", ex);
+        } catch (Exception ex) {
+            String msg = "Error deleting Realm in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+        return true;
+
+    }
+
+
+    public boolean configureOIDCFederatedIDP(String realmId, String displayName, String scopes, KeycloakClientSecret secret, Map<String, String> configs) {
+        Keycloak client = null;
+        try {
+
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+            RealmResource realmResource = client.realm(realmId);
+
+            List<IdentityProviderRepresentation> representations = realmResource.identityProviders().findAll();
+
+
+            for (IdentityProviderRepresentation representation : representations) {
+
+                realmResource.identityProviders().get(representation.getInternalId()).remove();
+
+            }
+
+
+            IdentityProviderRepresentation idp = new IdentityProviderRepresentation();
+
+            idp.setAlias("oidc");
+            idp.setDisplayName(displayName);
+            idp.setProviderId("oidc");
+            idp.setEnabled(true);
+            if (configs != null) {
+                idp.setConfig(configs);
+            }
+
+            idp.getConfig().put("clientId", secret.getClientId());
+            idp.getConfig().put("clientSecret", secret.getClientSecret());
+            idp.getConfig().put("authorizationUrl", ciLogonAuthorizationEndpoint);
+            idp.getConfig().put("tokenUrl", ciLogonTokenEndpoint);
+            idp.getConfig().put("userInfoUrl", ciLogonUserInfoEndpoint);
+            idp.getConfig().put("defaultScope", scopes);
+            idp.getConfig().put("issuer", ciLogonIssuerUri);
+            idp.getConfig().put("jwksUri", jwksUri);
+            idp.getConfig().put("forwardParameters", "idphint");
+
+            realmResource.identityProviders().create(idp);
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while configuring  IDP in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * This adds user attributes to users
+     *
+     * @param realmId
+     * @param attributeMap
+     * @param users
+     * @return
+     */
+    public boolean addUserAttributes(String realmId, String accessToken, Map<String, List<String>> attributeMap, List<String> users) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            RealmResource realmResource = client.realm(realmId);
+
+            for (String user : users) {
+
+                UserRepresentation userRepresentation = getUserByUsername(client, realmId, user.toLowerCase());
+
+                if (userRepresentation != null) {
+                    UserResource resource = realmResource.users().get(userRepresentation.getId());
+
+                    Map<String, List<String>> exAtrMap = userRepresentation.getAttributes();
+
+                    if (exAtrMap != null && !exAtrMap.isEmpty()) {
+                        attributeMap.keySet().forEach(key -> {
+                            exAtrMap.put(key, attributeMap.get(key));
+                        });
+                        userRepresentation.setAttributes(exAtrMap);
+                    } else {
+                        userRepresentation.setAttributes(attributeMap);
+                    }
+
+                    resource.update(userRepresentation);
+                }
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while adding user attributes in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+        return true;
+
+    }
+
+
+    /**
+     * This deletes user attributes of users
+     *
+     * @param realmId
+     * @param attributeMap
+     * @param users
+     * @return
+     */
+    public boolean deleteUserAttributes(String realmId, String accessToken, Map<String, List<String>> attributeMap, List<String> users) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            RealmResource realmResource = client.realm(realmId);
+
+            for (String user : users) {
+
+                UserRepresentation userRepresentation = getUserByUsername(client, realmId, user.toLowerCase());
+                UserResource resource = realmResource.users().get(userRepresentation.getId());
+
+                Map<String, List<String>> exAtrMap = userRepresentation.getAttributes();
+
+                if (exAtrMap != null && !exAtrMap.isEmpty()) {
+                    attributeMap.keySet().forEach(key -> {
+                        List<String> stringList = exAtrMap.get(key);
+                        if (stringList != null && !stringList.isEmpty()) {
+                            stringList.removeAll(attributeMap.get(key));
+                            exAtrMap.put(key, stringList);
+                        }
+                    });
+                    userRepresentation.setAttributes(exAtrMap);
+                }
+
+                resource.update(userRepresentation);
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting user attributes in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+        return true;
+
+    }
+
+    /**
+     * Create protocol mapper representation in given client
+     *
+     * @param protocolMapperRepresentations
+     * @param realmId
+     * @param clientId
+     * @return
+     */
+    public boolean addProtocolMapper(ProtocolMapperRepresentation protocolMapperRepresentations,
+                                     String realmId, String clientId) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            RealmResource realmResource = client.realm(realmId);
+
+            ClientRepresentation representation = realmResource.clients().findByClientId(clientId).get(0);
+
+
+            ProtocolMappersResource resource = realmResource.clients().get(representation.getId()).getProtocolMappers();
+            resource.createMapper(protocolMapperRepresentations);
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while adding protocol mappers in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * Get all users of given tenant
+     *
+     * @param realmId
+     * @return
+     */
+    public List<UserRepresentation> getAllUsers(String realmId) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            List<UserRepresentation> representations = client.realm(realmId).users().list();
+            List<UserRepresentation> representationList = new ArrayList<>();
+            if (representations != null && !representations.isEmpty()) {
+                for (UserRepresentation userRepresentation : representations) {
+                    UserRepresentation userRep = getUserByUsername(client, realmId, userRepresentation.getUsername());
+                    representationList.add(userRep);
+                }
+            }
+            return representationList;
+        } catch (Exception ex) {
+            String msg = "Error occurred while adding protocol mappers in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    /**
+     * Configure Roles in keycloak Realm or Client
+     *
+     * @param roleRepresentations
+     * @param realmId
+     * @param clientScope         if true add roles to client else to realm
+     * @return
+     */
+    public boolean addRoles(List<RoleRepresentation> roleRepresentations, String realmId, String clientId, boolean clientScope) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            RealmResource realmResource = client.realm(realmId);
+
+            if (clientScope) {
+                ClientRepresentation representation = realmResource.clients().findByClientId(clientId).get(0);
+
+                for (RoleRepresentation roleRepresentation : roleRepresentations) {
+                    realmResource.clients().get(representation.getId()).roles().create(roleRepresentation);
+                }
+
+            } else {
+
+                for (RoleRepresentation representation : roleRepresentations) {
+                    realmResource.roles().create(representation);
+                }
+
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while adding roles in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * Provides all Roles belongs to client, if clientId not present, provides all
+     * Roles related to Realm
+     *
+     * @param realmId
+     * @param clientId
+     */
+    public List<RoleRepresentation> getAllRoles(String realmId, String clientId) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            RealmResource realmResource = client.realm(realmId);
+
+            if (clientId != null) {
+
+                ClientRepresentation representation = realmResource.clients().findByClientId(clientId).get(0);
+
+                return realmResource.clients().get(representation.getId()).roles().list();
+
+            } else {
+                return realmResource.roles().list();
+
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while adding roles in Keycloak Server, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+
+    }
+
+    /**
+     * Configure event persistance for Keycloak Realms.
+     *
+     * @param realmId
+     * @param eventType
+     * @param time
+     * @param enabelEvents
+     * @param isAdminEvent
+     * @return
+     */
+    public boolean configureEventPersistence(String realmId, String eventType, long time, boolean enabelEvents, boolean isAdminEvent) {
+
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            RealmEventsConfigRepresentation representation = client.realm(realmId).getRealmEventsConfig();
+
+            if (isAdminEvent) {
+                representation.setAdminEventsEnabled(true);
+            } else {
+                representation.setEventsEnabled(enabelEvents);
+                representation.setEventsExpiration(time);
+                List<String> eventTypes = representation.getEnabledEventTypes();
+                if (eventTypes != null && !eventTypes.isEmpty() && !eventTypes.contains(eventType)) {
+                    eventTypes.add(eventType);
+
+                } else {
+                    eventTypes = new ArrayList<>();
+                    eventTypes.add(eventType);
+                }
+
+                representation.setEnabledEventTypes(eventTypes);
+
+                client.realm(realmId).updateRealmEventsConfig(representation);
+
+            }
+
+            return true;
+        } catch (Exception ex) {
+            String msg = "Error occurred while configuring event persistence events, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+
+    }
+
+
+    /**
+     * Get Last login event of given user
+     *
+     * @param realmId
+     * @param clientId
+     * @return
+     */
+    public EventRepresentation getLastLoginEvent(String realmId, String clientId, String username) {
+
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            List<EventRepresentation> eventRepresentations = client.realm(realmId).getEvents();
+
+            for (EventRepresentation representation : eventRepresentations) {
+                Map<String, String> map = representation.getDetails();
+
+
+                if (map != null && !map.isEmpty()) {
+                    for (String key : map.keySet()) {
+                        if (key.equals("username") && map.get(key).equals(username)) {
+                            return representation;
+                        }
+                    }
+                }
+            }
+
+            return null;
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling events, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+
+    }
+
+    /**
+     * provides last active session of given user
+     *
+     * @param realmId
+     * @param clientId
+     * @param accessToken
+     * @param username
+     * @return
+     */
+    public UserSessionRepresentation getLatestSession(String realmId, String clientId, String accessToken, String username) {
+
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            List<UserRepresentation> userResourceList = client.realm(realmId).users().search(
+                    username.toLowerCase(), null, null, null, null, null);
+
+            if (!userResourceList.isEmpty() && userResourceList.get(0).getUsername().equals(username.toLowerCase())) {
+                UserRepresentation userRepresentation = userResourceList.get(0);
+                List<UserSessionRepresentation> userSessionRepresentations = client.realm(realmId).users().get(userRepresentation.getId()).getUserSessions();
+
+                if (!userSessionRepresentations.isEmpty()) {
+                    return userSessionRepresentations.get(userSessionRepresentations.size() - 1);
+                }
+
+            }
+
+            return null;
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling active user sessions, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+
+    }
+
+    /**
+     * creates groups and child groups in Keycloak
+     *
+     * @param realmId
+     * @param clientId
+     * @param accessToken
+     * @param groupRepresentations
+     * @return
+     */
+    public List<GroupRepresentation> createGroups(String realmId, String clientId, String clientSec, List<GroupRepresentation> groupRepresentations) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            List<GroupRepresentation> representationList = new ArrayList<>();
+
+            for (GroupRepresentation representation : groupRepresentations) {
+
+
+                Response response = client.realm(realmId).groups().add(representation);
+
+
+                if (response.getStatus() == HttpStatus.SC_CREATED) {
+                    String id = getCreatedId(response);
+
+                    if (representation.getRealmRoles() != null && !representation.getRealmRoles().isEmpty()) {
+                        List<RoleRepresentation> roleRepresentation = new ArrayList<>();
+                        for (String role : representation.getRealmRoles()) {
+                            RoleResource resource = client.realm(realmId).roles().get(role);
+                            if (resource != null) {
+                                roleRepresentation.add(resource.toRepresentation());
+                            }
+                        }
+                        if (!roleRepresentation.isEmpty()) {
+                            client.realm(realmId).groups().group(id).roles().realmLevel().add(roleRepresentation);
+                        }
+
+                    }
+
+                    if (representation.getClientRoles() != null && !representation.getClientRoles().isEmpty()) {
+                        List<RoleRepresentation> clientRepresentations = new ArrayList<>();
+                        ClientRepresentation clientRepresentation =
+                                client.realm(realmId).clients().findByClientId(clientId).get(0);
+                        for (String role : representation.getClientRoles().get(clientId)) {
+
+                            RoleResource resource = client.realm(realmId).clients().get(clientRepresentation.getId()).roles().get(role);
+
+                            if (resource != null) {
+                                clientRepresentations.add(resource.toRepresentation());
+                            }
+                        }
+                        if (!clientRepresentations.isEmpty()) {
+                            client.realm(realmId).groups().group(id).roles().
+                                    clientLevel(clientRepresentation.getId()).add(clientRepresentations);
+                        }
+
+                    }
+
+                    representation.setId(id);
+                    this.createGroup(client, realmId, clientId, representation);
+                    response.close();
+                    GroupRepresentation savedRep =
+                            client.realm(realmId).groups().group(representation.getId()).toRepresentation();
+                    representationList.add(savedRep);
+                    return representationList;
+                } else if (response.getStatus() == HttpStatus.SC_UNAUTHORIZED) {
+                    String msg = "Error occurred while creating group, reason: HTTP " + response.getStatus() + " Unauthorized";
+                    LOGGER.error(msg);
+                    throw new RuntimeException(msg);
+                } else {
+                    String msg = "Error occurred while creating group, reason: HTTP  " + response.getStatus();
+                    LOGGER.error(msg);
+                    throw new RuntimeException(msg);
+                }
+            }
+        } catch (Exception ex) {
+            String msg = "Error occurred while creating group, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * Update given group
+     *
+     * @param realmId
+     * @param accessToken
+     * @param groupRepresentation
+     * @return
+     */
+    public GroupRepresentation updateGroup(String realmId, String clientId, String clientSec, GroupRepresentation groupRepresentation) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            client.realm(realmId).groups().
+                    group(groupRepresentation.getId()).update(groupRepresentation);
+
+            List<RoleRepresentation> exRoles =
+                    client.realm(realmId).groups().group(groupRepresentation.getId()).roles().realmLevel().listAll();
+
+            if (exRoles != null && !exRoles.isEmpty()) {
+                client.realm(realmId).groups().group(groupRepresentation.getId()).roles().realmLevel().remove(exRoles);
+            }
+
+            if (groupRepresentation.getRealmRoles() != null && !groupRepresentation.getRealmRoles().isEmpty()) {
+                List<RoleRepresentation> roleRepresentation = new ArrayList<>();
+                for (String role : groupRepresentation.getRealmRoles()) {
+                    RoleResource resource = client.realm(realmId).roles().get(role);
+                    if (resource != null) {
+                        roleRepresentation.add(resource.toRepresentation());
+                    }
+                }
+                if (!roleRepresentation.isEmpty()) {
+                    client.realm(realmId).groups().group(groupRepresentation.getId()).roles().realmLevel().add(roleRepresentation);
+                }
+
+            }
+
+            ClientRepresentation clientRepresentation =
+                    client.realm(realmId).clients().findByClientId(clientId).get(0);
+
+            List<RoleRepresentation> exClientRoles =
+                    client.realm(realmId).groups().group(groupRepresentation.getId())
+                            .roles().clientLevel(clientRepresentation.getId()).listAll();
+
+            if (exClientRoles != null && !exClientRoles.isEmpty()) {
+                client.realm(realmId).groups().group(groupRepresentation.getId())
+                        .roles().clientLevel(clientRepresentation.getId()).remove(exClientRoles);
+            }
+
+            if (groupRepresentation.getClientRoles() != null && !groupRepresentation.getClientRoles().isEmpty()) {
+                List<RoleRepresentation> clientRepresentations = new ArrayList<>();
+
+                for (String role : groupRepresentation.getClientRoles().get(clientId)) {
+
+                    RoleResource resource = client.realm(realmId).clients().get(clientRepresentation.getId()).roles().get(role);
+
+                    if (resource != null) {
+                        clientRepresentations.add(resource.toRepresentation());
+                    }
+                }
+                if (!clientRepresentations.isEmpty()) {
+                    client.realm(realmId).groups().group(groupRepresentation.getId()).roles().
+                            clientLevel(clientRepresentation.getId()).add(clientRepresentations);
+                }
+
+            }
+
+            return client.realm(realmId).groups().group(groupRepresentation.getId()).toRepresentation();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while updating group, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+
+    }
+
+
+    /**
+     * Delete given group
+     *
+     * @param realmId
+     * @param accessToken
+     * @param groupId
+     * @return
+     */
+    public boolean deleteGroup(String realmId, String clientId, String clientSec, String groupId) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            String id = client.realm(realmId).groups().
+                    group(groupId).toRepresentation().getId();
+
+            client.realm(realmId).groups().
+                    group(id).remove();
+
+            return true;
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting group, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+
+    }
+
+    /**
+     * find group by group Id or group name
+     *
+     * @param realmId
+     * @param accessToken
+     * @return
+     */
+    public GroupRepresentation findGroup(String realmId, String accessToken, String id, String name) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            if (id != null && !id.trim().equals("")) {
+                GroupResource resource = client.realm(realmId).groups().group(id);
+                if (resource != null) {
+                    return resource.toRepresentation();
+                }
+            } else {
+                List<GroupRepresentation> groupRepresentations = client.
+                        realm(realmId).groups().groups(name, 0, 1);
+                if (groupRepresentations != null && !groupRepresentations.isEmpty()) {
+                    return groupRepresentations.get(0);
+                }
+            }
+
+        } catch (Exception ex) {
+            if (ex.getMessage().contains("HTTP 404")) {
+                return null;
+            } else {
+                String msg = "Error occurred finding groups, reason: " + ex.getMessage();
+                LOGGER.error(msg, ex);
+                throw new RuntimeException(msg, ex);
+            }
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * pull all groups related to given realm
+     *
+     * @param realmId
+     * @param accessToken
+     * @return
+     */
+    public List<GroupRepresentation> getAllGroups(String realmId, String accessToken) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            List<GroupRepresentation> groupRepresentations = new ArrayList<>();
+
+
+            for (GroupRepresentation representation : client.realm(realmId).groups().groups()) {
+                groupRepresentations.
+                        add(client.realm(realmId).groups().group(representation.getId()).toRepresentation());
+            }
+
+            return groupRepresentations;
+
+
+        } catch (Exception ex) {
+            if (ex.getMessage().contains("HTTP 404")) {
+                return null;
+            } else {
+                String msg = "Error occurred finding groups, reason: " + ex.getMessage();
+                LOGGER.error(msg, ex);
+                throw new RuntimeException(msg, ex);
+            }
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean addUserToGroup(String realmId, String username, String groupId, String accessToken) {
+
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+
+            client.realm(realmId).users().get(userRepresentation.getId()).joinGroup(groupId);
+            return true;
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while adding user to group, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean removeUserFromGroup(String realmId, String username, String groupId, String accessToken) {
+
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            UserRepresentation userRepresentation = getUserByUsername(client, realmId, username);
+
+            client.realm(realmId).users().get(userRepresentation.getId()).leaveGroup(groupId);
+            return true;
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while remove user from group, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+    }
+
+
+    public boolean configureAgentClient(String realmId, String clientId, long accessTokenLifeTime) {
+        Keycloak client = null;
+        try {
+
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            ClientRepresentation representation = client.realm(realmId).clients().findByClientId(clientId).get(0);
+
+            if (representation != null) {
+                Map<String, String> attributes = representation.getAttributes();
+
+                if (attributes == null || attributes.isEmpty()) {
+                    attributes = new HashMap<>();
+                }
+                attributes.put("access.token.lifespan", String.valueOf(accessTokenLifeTime));
+
+                client.realm(realmId).clients().get(representation.getId()).update(representation);
+                return true;
+
+            }
+
+            return false;
+        } catch (Exception ex) {
+            String msg = "Error occurred while remove user from group, reason: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+
+    }
+
+
+    public boolean isValidEndUser(String realmId, String username, String accessToken) {
+        Keycloak client = null;
+        try {
+
+            client = getClient(iamServerURL, realmId, accessToken);
+
+            return isValidEndUser(client, realmId, username);
+        } catch (Exception ex) {
+            String msg = "Error occurred end user validity: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+
+
+    }
+
+    public boolean isValidEndUser(String realmId, String username) {
+        Keycloak client = null;
+        try {
+            client = getClient(iamServerURL, superAdminRealmID, superAdminUserName, superAdminPassword);
+
+            return isValidEndUser(client, realmId, username);
+        } catch (Exception ex) {
+            String msg = "Error occurred end user validity: " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            throw new RuntimeException(msg, ex);
+        } finally {
+            if (client != null) {
+                client.close();
+            }
+        }
+
+
+    }
+
+
+    private boolean isValidEndUser(Keycloak client, String realmId, String username) {
+        UserRepresentation representation = getUserByUsername(client, realmId, username);
+
+        if (representation == null) {
+            return false;
+        }
+
+        Map<String, List<String>> attributes = representation.getAttributes();
+
+        if (attributes != null && !attributes.isEmpty()) {
+
+            for (String key : attributes.keySet()) {
+                if (key.equals(Constants.CUSTOS_REALM_AGENT)) {
+                    return false;
+                }
+
+            }
+        }
+        return true;
+    }
+
+
+    private ResteasyClient getRestClient() {
+        return new ResteasyClientBuilder()
+                .connectionPoolSize(POOL_SIZE)
+                .trustStore(loadKeyStore())
+                .build();
+    }
+
+    private Keycloak getClient(String adminUrl, String realm, String loginUsername, String password) {
+
+        return KeycloakUtils.getClient(adminUrl, realm, loginUsername,
+                password, clientId, trustStorePath, truststorePassword);
+    }
+
+    private Keycloak getClient(String adminUrl, String realm, String accessToken) {
+
+        return KeycloakUtils.getClient(adminUrl, realm, accessToken, trustStorePath, truststorePassword);
+    }
+
+    private KeyStore loadKeyStore() {
+
+        InputStream is = null;
+        try {
+
+
+            File trustStoreFile = new File(trustStorePath);
+
+            if (trustStoreFile.exists()) {
+                LOGGER.debug("Loading trust store file from path " + trustStorePath);
+                is = new FileInputStream(trustStorePath);
+            } else {
+                LOGGER.debug("Trying to load trust store file form class path " + trustStorePath);
+                is = SecurityUtil.class.getClassLoader().getResourceAsStream(trustStorePath);
+                if (is != null) {
+                    LOGGER.debug("Trust store file was loaded form class path " + trustStorePath);
+                }
+            }
+
+            if (is == null) {
+                throw new RuntimeException("Could not find a trust store file in path " + trustStorePath);
+            }
+
+            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+            ks.load(is, truststorePassword.toCharArray());
+            return ks;
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to load trust store KeyStore instance", e);
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    LOGGER.error("Failed to close trust store FileInputStream", e);
+                }
+            }
+        }
+    }
+
+
+    private RealmRepresentation createDefaultRoles(RealmRepresentation realmDetails) {
+        List<RoleRepresentation> defaultRoles = new ArrayList<RoleRepresentation>();
+        RoleRepresentation adminRole = new RoleRepresentation();
+        adminRole.setName("admin");
+        adminRole.setDescription("Admin role for PGA users");
+        defaultRoles.add(adminRole);
+        RoleRepresentation adminReadOnlyRole = new RoleRepresentation();
+        adminReadOnlyRole.setName("admin-read-only");
+        adminReadOnlyRole.setDescription("Read only role for PGA Admin users");
+        defaultRoles.add(adminReadOnlyRole);
+        RoleRepresentation gatewayUserRole = new RoleRepresentation();
+        gatewayUserRole.setName("gateway-user");
+        gatewayUserRole.setDescription("default role for PGA users");
+        defaultRoles.add(gatewayUserRole);
+        RoleRepresentation pendingUserRole = new RoleRepresentation();
+        pendingUserRole.setName("user-pending");
+        pendingUserRole.setDescription("role for newly registered PGA users");
+        defaultRoles.add(pendingUserRole);
+        RoleRepresentation gatewayProviderRole = new RoleRepresentation();
+        gatewayProviderRole.setName("gateway-provider");
+        gatewayProviderRole.setDescription("role for gateway providers in the super-admin PGA");
+        defaultRoles.add(gatewayProviderRole);
+        RolesRepresentation rolesRepresentation = new RolesRepresentation();
+        rolesRepresentation.setRealm(defaultRoles);
+        realmDetails.setRoles(rolesRepresentation);
+        return realmDetails;
+    }
+
+
+    private String getRealmManagementClientId(Keycloak client, String realmId) {
+        List<ClientRepresentation> realmClients = client.realm(realmId).clients().findAll();
+        String realmManagementClientId = null;
+        for (ClientRepresentation realmClient : realmClients) {
+            if (realmClient.getClientId().equals("realm-management")) {
+                realmManagementClientId = realmClient.getId();
+            }
+        }
+        return realmManagementClientId;
+    }
+
+
+    private UserRepresentation getUserByUsername(Keycloak client, String tenantId, String username) {
+
+        // Searching for users by username returns also partial matches, so need to filter down to an exact match if it exists
+        List<UserRepresentation> userResourceList = client.realm(tenantId).users().search(
+                username.toLowerCase(), null, null, null, null, null);
+
+        for (UserRepresentation userRepresentation : userResourceList) {
+            if (userRepresentation.getUsername().equals(username.toLowerCase())) {
+                RoleMappingResource resource = client.realm(tenantId).users().get(userRepresentation.getId()).roles();
+                MappingsRepresentation representation = resource.getAll();
+                if (representation != null && representation.getRealmMappings() != null) {
+                    List<String> roleRepresentations = new ArrayList<>();
+                    representation.getRealmMappings().forEach(t -> roleRepresentations.add(t.getName()));
+                    userRepresentation.setRealmRoles(roleRepresentations);
+                }
+                if (representation != null && representation.getClientMappings() != null) {
+                    Map<String, List<String>> roleRepresentations = new HashMap<>();
+                    representation.getClientMappings().keySet().forEach(key -> {
+                        if (representation.getClientMappings().get(key).getMappings() != null) {
+                            List<String> roleList = new ArrayList<>();
+                            representation.getClientMappings().get(key).getMappings().forEach(t -> roleList.add(t.getName()));
+                            roleRepresentations.put(key, roleList);
+                        }
+                    });
+                    userRepresentation.setClientRoles(roleRepresentations);
+                }
+
+                return userRepresentation;
+            }
+        }
+        return null;
+    }
+
+
+    private boolean createGroup(Keycloak client, String realmId, String clientId, GroupRepresentation parentRepresentation) {
+
+        if (parentRepresentation.getSubGroups() != null && !parentRepresentation.getSubGroups().isEmpty()) {
+            List<GroupRepresentation> groupRepresentations = parentRepresentation.getSubGroups();
+            if (groupRepresentations != null && !groupRepresentations.isEmpty()) {
+                for (GroupRepresentation representation : groupRepresentations) {
+                    Response createdRes = client.realm(realmId).groups().add(representation);
+                    String id = getCreatedId(createdRes);
+                    if (id != null) {
+                        representation.setId(id);
+                        Response response = client.realm(realmId).groups().group(parentRepresentation.getId()).subGroup(representation);
+                        if (response.getStatus() == HttpStatus.SC_CREATED || response.getStatus() == HttpStatus.SC_NO_CONTENT) {
+                            if (representation.getRealmRoles() != null && !representation.getRealmRoles().isEmpty()) {
+                                List<RoleRepresentation> roleRepresentation = new ArrayList<>();
+                                for (String role : representation.getRealmRoles()) {
+                                    RoleResource resource = client.realm(realmId).roles().get(role);
+                                    if (resource != null) {
+                                        roleRepresentation.add(resource.toRepresentation());
+                                    }
+                                }
+                                if (!roleRepresentation.isEmpty()) {
+                                    client.realm(realmId).groups().group(id).roles().realmLevel().add(roleRepresentation);
+                                }
+
+                            }
+
+                            if (representation.getClientRoles() != null && !representation.getClientRoles().isEmpty()) {
+                                List<RoleRepresentation> clientRepresentations = new ArrayList<>();
+                                ClientRepresentation clientRepresentation =
+                                        client.realm(realmId).clients().findByClientId(clientId).get(0);
+                                for (String role : representation.getClientRoles().get(clientId)) {
+                                    RoleResource resource = client.realm(realmId).clients().get(clientRepresentation.getId()).roles().get(role);
+
+                                    if (resource != null) {
+                                        clientRepresentations.add(resource.toRepresentation());
+                                    }
+                                }
+                                if (!clientRepresentations.isEmpty()) {
+                                    client.realm(realmId).groups().group(id).roles().
+                                            clientLevel(clientRepresentation.getId()).add(clientRepresentations);
+                                }
+
+                            }
+                            createGroup(client, realmId, clientId, representation);
+                        }
+                        response.close();
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+
+    private List<UserRepresentation> searchUsers(Keycloak client, String tenantId, String username,
+                                                 String firstName, String lastName, String email, String search, int offset, int limit) {
+
+        // Searching for users by username returns also partial matches, so need to filter down to an exact match if it exists
+        List<UserRepresentation> userResourceList = null;
+        if (search != null && !search.trim().equals("")) {
+            userResourceList = client.realm(tenantId).users().search(search, offset, limit);
+        } else {
+
+            userResourceList = client.realm(tenantId).users().search(
+                    username.toLowerCase(), firstName, lastName, email, offset, limit);
+        }
+
+        if (userResourceList != null && !userResourceList.isEmpty()) {
+            List<UserRepresentation> newList = new ArrayList<>();
+            for (UserRepresentation userRepresentation : userResourceList) {
+                RoleMappingResource resource = client.realm(tenantId).users().get(userRepresentation.getId()).roles();
+                MappingsRepresentation representation = resource.getAll();
+                if (representation != null && representation.getRealmMappings() != null) {
+                    List<String> roleRepresentations = new ArrayList<>();
+                    representation.getRealmMappings().forEach(t -> roleRepresentations.add(t.getName()));
+                    userRepresentation.setRealmRoles(roleRepresentations);
+                }
+                if (representation != null && representation.getClientMappings() != null) {
+                    Map<String, List<String>> roleRepresentations = new HashMap<>();
+                    representation.getClientMappings().keySet().forEach(key -> {
+                        if (representation.getClientMappings().get(key).getMappings() != null) {
+                            List<String> roleList = new ArrayList<>();
+                            representation.getClientMappings().get(key).getMappings().forEach(t -> roleList.add(t.getName()));
+                            roleRepresentations.put(key, roleList);
+                        }
+                    });
+                    userRepresentation.setClientRoles(roleRepresentations);
+                }
+                newList.add(userRepresentation);
+            }
+            return userResourceList;
+        }
+
+        return userResourceList;
+    }
+
+    private String getCreatedId(Response response) {
+        URI location = response.getLocation();
+        if (location == null) {
+            return null;
+        }
+        String path = location.getPath();
+        return path.substring(path.lastIndexOf('/') + 1);
+    }
+
+
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClientSecret.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClientSecret.java
new file mode 100644
index 0000000..559b683
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakClientSecret.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.keycloak;
+
+/**
+ * Represents the keycloak client Id and client secret
+ */
+public class KeycloakClientSecret {
+
+    private String clientId;
+
+    private String clientSecret;
+
+    public KeycloakClientSecret(String clientId, String clientSecret) {
+        this.clientId = clientId;
+        this.clientSecret = clientSecret;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public String getClientSecret() {
+        return clientSecret;
+    }
+
+    public void setClientSecret(String clientSecret) {
+        this.clientSecret = clientSecret;
+    }
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakUtils.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakUtils.java
new file mode 100644
index 0000000..723a6fb
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/KeycloakUtils.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.keycloak;
+
+import org.apache.catalina.security.SecurityUtil;
+import org.jboss.resteasy.client.jaxrs.ResteasyClient;
+import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
+import org.keycloak.admin.client.Keycloak;
+import org.keycloak.admin.client.KeycloakBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.*;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+
+public class KeycloakUtils {
+
+    private final static int POOL_SIZE = 10;
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(KeycloakUtils.class);
+
+
+    public static Keycloak getClient (String serverURL, String realm, String accessToken,
+                                      String trustStorePath, String trustorePassword) {
+
+        return KeycloakBuilder.builder()
+                .serverUrl(serverURL)
+                .realm(realm)
+                .authorization(accessToken)
+                .resteasyClient(getRestClient(trustStorePath,trustorePassword))
+                .build();
+    }
+
+
+    public static Keycloak getClient(String serverURL, String realm, String loginUsername,
+                                     String password, String clientId, String trustStorePath, String trustorePassword) {
+
+        return KeycloakBuilder.builder()
+                .serverUrl(serverURL)
+                .realm(realm)
+                .username(loginUsername)
+                .password(password)
+                .clientId(clientId)
+                .resteasyClient(getRestClient(trustStorePath, trustorePassword))
+                .build();
+    }
+
+
+    private static ResteasyClient getRestClient(String trustorePath, String trustorePassword) {
+        return new ResteasyClientBuilder()
+                .connectionPoolSize(POOL_SIZE)
+                .trustStore(loadKeyStore(trustorePath, trustorePassword))
+                .build();
+    }
+
+
+    private static KeyStore loadKeyStore(String trustStorePath, String trustorePassword) {
+
+        InputStream is = null;
+        try {
+
+
+            File trustStoreFile = new File(trustStorePath);
+
+            if (trustStoreFile.exists()) {
+                LOGGER.debug("Loading trust store file from path " + trustStorePath);
+                is = new FileInputStream(trustStorePath);
+            } else {
+                LOGGER.debug("Trying to load trust store file form class path " + trustStorePath);
+                is = SecurityUtil.class.getClassLoader().getResourceAsStream(trustStorePath);
+                if (is != null) {
+                    LOGGER.debug("Trust store file was loaded form class path " + trustStorePath);
+                }
+            }
+
+            if (is == null) {
+                throw new RuntimeException("Could not find a trust store file in path " + trustStorePath);
+            }
+
+            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+            ks.load(is, trustorePassword.toCharArray());
+            return ks;
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to load trust store KeyStore instance", e);
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    LOGGER.error("Failed to close trust store FileInputStream", e);
+                }
+            }
+        }
+    }
+
+
+    public static SSLContext initializeTrustStoreManager(String trustStorePath, String trustStorePassword) throws
+            IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, KeyManagementException {
+
+            File trustStoreFile = new File(trustStorePath);
+            InputStream is;
+            if (trustStoreFile.exists()) {
+                LOGGER.debug("Loading trust store file from path " + trustStorePath);
+                is = new FileInputStream(trustStorePath);
+            } else {
+                LOGGER.debug("Trying to load trust store file form class path " + trustStorePath);
+                is = SecurityUtil.class.getClassLoader().getResourceAsStream(trustStorePath);
+                if (is != null) {
+                    LOGGER.debug("Trust store file was loaded form class path " + trustStorePath);
+                }
+            }
+
+            if (is == null) {
+                throw new RuntimeException("Could not find a trust store file in path " + trustStorePath);
+            }
+
+            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+
+            char[] trustPassword = trustStorePassword.toCharArray();
+
+            trustStore.load(is, trustPassword);
+
+            // initialize a trust manager factory
+            TrustManagerFactory trustFactory =
+                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+            trustFactory.init(trustStore);
+
+            // get the trust managers from the factory
+            TrustManager[] trustManagers = trustFactory.getTrustManagers();
+
+            // initialize an ssl context to use these managers and set as default
+            SSLContext sslContext = SSLContext.getInstance("SSL");
+            sslContext.init(null, trustManagers, null);
+            SSLContext.setDefault(sslContext);
+            return sslContext;
+
+    }
+
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/UnauthorizedException.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/UnauthorizedException.java
new file mode 100644
index 0000000..2a818f4
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/UnauthorizedException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.keycloak;
+
+/**
+ * UnAuthorized Exception
+ */
+public class UnauthorizedException extends Exception {
+
+    public UnauthorizedException(String msg, Throwable throwable) {
+        super(msg, throwable);
+    }
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/KeycloakAuthClient.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/KeycloakAuthClient.java
new file mode 100644
index 0000000..908f901
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/KeycloakAuthClient.java
@@ -0,0 +1,560 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.keycloak.auth;
+
+import org.apache.custos.federated.services.clients.keycloak.KeycloakUtils;
+import org.apache.http.Consts;
+import org.apache.http.HttpHeaders;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.keycloak.authorization.client.AuthzClient;
+import org.keycloak.authorization.client.Configuration;
+import org.keycloak.representations.AccessTokenResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.*;
+
+/**
+ * Acting as a broker between keycloak server and auth services
+ */
+@Component
+public class KeycloakAuthClient {
+
+    @Value("${iam.server.url:https://keycloak.custos.scigap.org:31000/auth/}")
+    private String idpServerURL;
+
+    @Value("${iam.server.truststore.path:/home/ubuntu/keystore/keycloak-client-truststore.pkcs12}")
+    private String trustStorePath;
+
+    @Value("${iam.server.truststore.password:keycloak}")
+    private String trustStorePassword;
+
+    @Value("${introspection.endpoint}")
+    private String introEndpoint;
+
+    @Value("${issuer}")
+    private String issuer;
+
+    @Value("${authorization.endpoint}")
+    private String authorizationEndpoint;
+
+    @Value("${token.endpoint}")
+    private String tokenEndpoint;
+
+    @Value("${end.session.endpoint}")
+    private String sessionEndpoint;
+
+    @Value("${jwks_uri}")
+    private String jwksUri;
+
+    @Value("${registration.endpoint}")
+    private String registrationEndpoint;
+
+    @Value("${user.info.endpoint}")
+    private String userInfoEndpoint;
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(KeycloakAuthClient.class);
+
+    public KeycloakAuthClient() {
+
+    }
+
+    @EventListener(ApplicationReadyEvent.class)
+    public void initializeSecurity() throws CertificateException, NoSuchAlgorithmException,
+            KeyStoreException, KeyManagementException, IOException {
+        try {
+            LOGGER.info("initializing security requirements");
+            KeycloakUtils.initializeTrustStoreManager(trustStorePath, trustStorePassword);
+        } catch (Exception ex) {
+            LOGGER.error("Keycloak Authclient initialization failed " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+
+    public String authenticate(String clientId, String clientSecret, String realmId, String username, String password) {
+
+        try {
+            Map<String, Object> clientCredentials = new HashMap<>();
+            clientCredentials.put("secret", clientSecret);
+            SSLContextBuilder builder = new SSLContextBuilder();
+
+            builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
+
+
+            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
+            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
+
+            Configuration configuration = new Configuration(idpServerURL,
+                    realmId, clientId, clientCredentials, httpclient);
+            AuthzClient keycloakClient = AuthzClient.create(configuration);
+
+
+            AccessTokenResponse accessToken = keycloakClient.obtainAccessToken(username, password);
+
+
+            if (accessToken != null) {
+                return accessToken.getToken();
+            }
+
+            return null;
+
+        } catch (Exception e) {
+            String msg = "Error occurred while authenticating " + e;
+            LOGGER.error(msg);
+            throw new RuntimeException(msg, e);
+        }
+
+    }
+
+
+    public boolean isUserAuthenticated(String username, String realmId, String accessToken) {
+        try {
+            User userInfo = getUserInfo(realmId, accessToken);
+            if (!username.equals(userInfo.getUsername())) {
+                throw new RuntimeException("Subject name and username for the token doesn't match");
+            }
+            return true;
+        } catch (Exception e) {
+            String msg = "Error occurred while checking if user: " + username + " is authorized in gateway: " + realmId;
+            LOGGER.error(msg, e);
+            throw new RuntimeException(msg, e);
+        }
+
+    }
+
+
+    public User getUser(String accessToken, String realmId) {
+        try {
+            return getUserInfo(realmId, accessToken);
+        } catch (Exception e) {
+            String msg = "Error occurred while retrieving user info " + e;
+            LOGGER.error(msg);
+            throw new RuntimeException(msg, e);
+        }
+
+    }
+
+    public String getUserManagementServiceAccountAccessToken(String clientId, String clientSecret,
+                                                             String realmId) {
+        try {
+            String tokenURL = getTokenEndpoint(realmId);
+            JSONObject clientCredentials = getClientCredentials(tokenURL, clientId, clientSecret);
+            return clientCredentials.getString("access_token");
+        } catch (Exception e) {
+            String msg = "Error occurred while retrieving service account access token  " + e;
+            LOGGER.error(msg);
+            throw new RuntimeException(msg, e);
+        }
+    }
+
+    public JSONObject getAccessToken(String clientId, String clientSecret, String realmId,
+                                     String code, String redirectUri) throws JSONException {
+        try {
+            String tokenURL = getTokenEndpoint(realmId);
+            return getTokenFromOAuthCode(tokenURL, clientId, clientSecret, code, redirectUri);
+
+        } catch (Exception e) {
+            String msg = "Error occurred while retrieving  access token  " + e;
+            LOGGER.error(msg);
+            throw new RuntimeException(msg, e);
+        }
+
+    }
+
+    public JSONObject getAccessTokenFromPasswordGrantType(String clientId, String clientSecret, String realmId,
+                                                          String username, String password) throws JSONException {
+        try {
+            String tokenURL = getTokenEndpoint(realmId);
+            return getTokenFromPasswordType(tokenURL, clientId, clientSecret, username, password);
+
+        } catch (Exception e) {
+            String msg = "Error occurred while retrieving  access token  " + e;
+            LOGGER.error(msg);
+            throw new RuntimeException(msg, e);
+        }
+
+    }
+
+    public JSONObject getAccessTokenFromRefreshTokenGrantType(String clientId, String clientSecret, String realmId,
+                                                              String refreshToken) throws JSONException {
+        try {
+            String tokenURL = getTokenEndpoint(realmId);
+            return getTokenFromRefreshToken(tokenURL, clientId, clientSecret, refreshToken);
+
+        } catch (Exception e) {
+            String msg = "Error occurred while retrieving  access token  " + e;
+            LOGGER.error(msg);
+            throw new RuntimeException(msg, e);
+        }
+
+    }
+
+    public JSONObject getAccessTokenFromClientCredentialsGrantType(String clientId, String clientSecret, String realmId
+    ) throws JSONException {
+        try {
+            String tokenURL = getTokenEndpoint(realmId);
+            return getClientCredentials(tokenURL, clientId, clientSecret);
+
+        } catch (Exception e) {
+            String msg = "Error occurred while retrieving  access token  " + e;
+            LOGGER.error(msg);
+            throw new RuntimeException(msg, e);
+        }
+
+    }
+
+    public JSONObject getJWTVerificationCerts(String clientId, String clientSecret, String realmId
+    ) throws JSONException {
+        try {
+            String tokenURL = getJwksUri(realmId);
+            return getJWKSResponse(tokenURL, clientId, clientSecret);
+
+        } catch (Exception e) {
+            String msg = "Error occurred while retrieving  access token  " + e;
+            LOGGER.error(msg);
+            throw new RuntimeException(msg, e);
+        }
+
+    }
+
+    public boolean revokeRefreshToken(String clientId, String clientSecret, String realmId, String refreshToken) throws JSONException {
+        try {
+            String tokenURL = getEndSessionEndpoint(realmId);
+            endSession(tokenURL, clientId, clientSecret, refreshToken);
+            return true;
+        } catch (Exception e) {
+            String msg = "Error occurred while  revoking refresh token  " + e;
+            LOGGER.error(msg, e);
+            throw new RuntimeException(msg, e);
+        }
+
+    }
+
+    private String getTokenEndpoint(String gatewayId) throws Exception {
+        String openIdConnectUrl = getOpenIDConfigurationUrl(gatewayId);
+        JSONObject openIdConnectConfig = new JSONObject(getFromUrl(openIdConnectUrl, null));
+        return openIdConnectConfig.getString("token_endpoint");
+    }
+
+    private String getJwksUri(String gatewayId) throws Exception {
+        String openIdConnectUrl = getOpenIDConfigurationUrl(gatewayId);
+        JSONObject openIdConnectConfig = new JSONObject(getFromUrl(openIdConnectUrl, null));
+        return openIdConnectConfig.getString("jwks_uri");
+    }
+
+    public String getAuthorizationEndpoint(String gatewayId) throws Exception {
+        String openIdConnectUrl = getOpenIDConfigurationUrl(gatewayId);
+        JSONObject openIdConnectConfig = new JSONObject(getFromUrl(openIdConnectUrl, null));
+        return openIdConnectConfig.getString("authorization_endpoint");
+    }
+
+    public String getEndSessionEndpoint(String gatewayId) throws Exception {
+        String openIdConnectUrl = getOpenIDConfigurationUrl(gatewayId);
+        JSONObject openIdConnectConfig = new JSONObject(getFromUrl(openIdConnectUrl, null));
+        return openIdConnectConfig.getString("end_session_endpoint");
+    }
+
+    public JSONObject getOIDCConfiguration(String tenantId, String clientId) throws Exception {
+        String openIdConnectUrl = getOpenIDConfigurationUrl(tenantId);
+        JSONObject openIdConnectConfig = new JSONObject(getFromUrl(openIdConnectUrl, null));
+
+        // openIdConnectConfig.put("introspection_endpoint", introEndpoint);
+        // openIdConnectConfig.put("issuer", issuer);
+        openIdConnectConfig.put("custos_token_endpoint", tokenEndpoint);
+        //  openIdConnectConfig.put("end_session_endpoint", sessionEndpoint);
+        //  openIdConnectConfig.put("token_introspection_endpoint", introEndpoint);
+        openIdConnectConfig.put("custos_userinfo_endpoint", userInfoEndpoint);
+        // openIdConnectConfig.put("jwks_uri", jwksUri);
+        openIdConnectConfig.put("registration_endpoint", registrationEndpoint);
+        // openIdConnectConfig.remove("check_session_iframe");
+
+
+        return openIdConnectConfig;
+    }
+
+    private User getUserInfo(String realmId, String token) throws Exception {
+        String openIdConnectUrl = getOpenIDConfigurationUrl(realmId);
+        JSONObject openIdConnectConfig = new JSONObject(getFromUrl(openIdConnectUrl, null));
+        String userInfoEndPoint = openIdConnectConfig.getString("userinfo_endpoint");
+        JSONObject userInfo = new JSONObject(getFromUrl(userInfoEndPoint, token));
+        return new User(userInfo.getString("sub"),
+                userInfo.getString("name"),
+                userInfo.getString("given_name"),
+                userInfo.getString("family_name"),
+                userInfo.getString("email"),
+                userInfo.getString("preferred_username"));
+    }
+
+
+    private String getOpenIDConfigurationUrl(String realm) {
+        return idpServerURL + "realms/" + realm + "/.well-known/openid-configuration";
+    }
+
+    private String getFromUrl(String urlToRead, String token) throws Exception {
+        StringBuilder result = new StringBuilder();
+        URL url = new URL(urlToRead);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        conn.setRequestMethod("GET");
+        conn.setDoInput(true);
+        if (token != null) {
+            String bearerAuth = "Bearer " + token;
+            conn.setRequestProperty("Authorization", bearerAuth);
+        }
+        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+        try {
+            String line;
+            while ((line = rd.readLine()) != null) {
+                result.append(line);
+            }
+        } finally {
+            rd.close();
+        }
+        return result.toString();
+    }
+
+
+    private JSONObject getClientCredentials(String tokenURL, String clientId, String clientSecret) {
+
+        CloseableHttpClient httpClient = HttpClients.createSystem();
+
+        HttpPost httpPost = new HttpPost(tokenURL);
+        String encoded = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8));
+        httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
+        List<NameValuePair> formParams = new ArrayList<>();
+        formParams.add(new BasicNameValuePair("grant_type", "client_credentials"));
+        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
+        httpPost.setEntity(entity);
+        try {
+            CloseableHttpResponse response = httpClient.execute(httpPost);
+            try {
+                String responseBody = EntityUtils.toString(response.getEntity());
+                JSONObject tokenInfo = new JSONObject(responseBody);
+                return tokenInfo;
+            } finally {
+                response.close();
+            }
+        } catch (IOException | JSONException e) {
+            throw new RuntimeException(e);
+        } finally {
+            try {
+                httpClient.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private JSONObject getTokenFromOAuthCode(String tokenURL, String clientId, String clientSecret, String code,
+                                             String redirect_uri) {
+
+        CloseableHttpClient httpClient = HttpClients.createSystem();
+
+        HttpPost httpPost = new HttpPost(tokenURL);
+        String encoded = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8));
+        httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
+        List<NameValuePair> formParams = new ArrayList<>();
+        formParams.add(new BasicNameValuePair("grant_type", "authorization_code"));
+        formParams.add(new BasicNameValuePair("code", code));
+        formParams.add(new BasicNameValuePair("redirect_uri", redirect_uri));
+        formParams.add(new BasicNameValuePair("client_id", clientId));
+        formParams.add(new BasicNameValuePair("client_secret", clientSecret));
+        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
+        httpPost.setEntity(entity);
+        try {
+            CloseableHttpResponse response = httpClient.execute(httpPost);
+            try {
+                String responseBody = EntityUtils.toString(response.getEntity());
+                JSONObject tokenInfo = new JSONObject(responseBody);
+                return tokenInfo;
+            } finally {
+                response.close();
+            }
+        } catch (IOException | JSONException e) {
+            throw new RuntimeException(e);
+        } finally {
+            try {
+                httpClient.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private void endSession(String endSessionEndpoint, String clientId, String clientSecret, String refreshToken) {
+
+        CloseableHttpClient httpClient = HttpClients.createSystem();
+
+        HttpPost httpPost = new HttpPost(endSessionEndpoint);
+        String encoded = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8));
+        httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
+        List<NameValuePair> formParams = new ArrayList<>();
+        formParams.add(new BasicNameValuePair("refresh_token", refreshToken));
+        formParams.add(new BasicNameValuePair("client_id", clientId));
+        formParams.add(new BasicNameValuePair("client_secret", clientSecret));
+        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
+        httpPost.setEntity(entity);
+        try {
+            CloseableHttpResponse response = httpClient.execute(httpPost);
+            response.close();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            try {
+                httpClient.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private JSONObject getJWKSResponse(String jwksUri, String clientId, String clientSecret) {
+
+        CloseableHttpClient httpClient = HttpClients.createSystem();
+
+        HttpGet httpPost = new HttpGet(jwksUri);
+        String encoded = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8));
+        httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
+        try {
+            CloseableHttpResponse response = httpClient.execute(httpPost);
+            try {
+                String responseBody = EntityUtils.toString(response.getEntity());
+                JSONObject tokenInfo = new JSONObject(responseBody);
+                return tokenInfo;
+            } finally {
+                response.close();
+            }
+        } catch (IOException | JSONException e) {
+            throw new RuntimeException(e);
+        } finally {
+            try {
+                httpClient.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+
+    private JSONObject getTokenFromPasswordType(String tokenURL, String clientId, String clientSecret, String username,
+                                                String password) {
+
+        CloseableHttpClient httpClient = HttpClients.createSystem();
+
+        HttpPost httpPost = new HttpPost(tokenURL);
+        String encoded = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8));
+        httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
+        List<NameValuePair> formParams = new ArrayList<>();
+        formParams.add(new BasicNameValuePair("grant_type", "password"));
+        formParams.add(new BasicNameValuePair("username", username));
+        formParams.add(new BasicNameValuePair("password", password));
+        formParams.add(new BasicNameValuePair("client_id", clientId));
+        formParams.add(new BasicNameValuePair("client_secret", clientSecret));
+        formParams.add(new BasicNameValuePair("scope", "openid"));
+        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
+        httpPost.setEntity(entity);
+        try {
+            CloseableHttpResponse response = httpClient.execute(httpPost);
+            try {
+                String responseBody = EntityUtils.toString(response.getEntity());
+                JSONObject tokenInfo = new JSONObject(responseBody);
+                return tokenInfo;
+            } finally {
+                response.close();
+            }
+        } catch (IOException | JSONException e) {
+            throw new RuntimeException(e);
+        } finally {
+            try {
+                httpClient.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+
+    private JSONObject getTokenFromRefreshToken(String tokenURL, String clientId, String clientSecret, String refreshToken) {
+
+        CloseableHttpClient httpClient = HttpClients.createSystem();
+
+        HttpPost httpPost = new HttpPost(tokenURL);
+        String encoded = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8));
+        httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
+        List<NameValuePair> formParams = new ArrayList<>();
+        formParams.add(new BasicNameValuePair("grant_type", "refresh_token"));
+        formParams.add(new BasicNameValuePair("refresh_token", refreshToken));
+        formParams.add(new BasicNameValuePair("client_id", clientId));
+        formParams.add(new BasicNameValuePair("client_secret", clientSecret));
+        formParams.add(new BasicNameValuePair("scope", "openid"));
+        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
+        httpPost.setEntity(entity);
+        try {
+            CloseableHttpResponse response = httpClient.execute(httpPost);
+            try {
+                String responseBody = EntityUtils.toString(response.getEntity());
+                JSONObject tokenInfo = new JSONObject(responseBody);
+                return tokenInfo;
+            } finally {
+                response.close();
+            }
+        } catch (IOException | JSONException e) {
+            throw new RuntimeException(e);
+        } finally {
+            try {
+                httpClient.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+
+
+
+
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/TokenResponse.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/TokenResponse.java
new file mode 100644
index 0000000..cc7363a
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/TokenResponse.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.keycloak.auth;
+
+/**
+ * This class wraps all the attributes provided from the token response
+ */
+public class TokenResponse {
+    private String accessToken;
+    private double expiresIn;
+    private double refreshExpiresIn;
+    private String refreshToken;
+    private String tokenType;
+    private String idToken;
+    private double notBeforePolicy;
+    private String sessionState;
+    private String scope;
+
+    public TokenResponse(String accessToken, double expiresIn, double refreshExpiresIn, String refreshToken,
+                         String tokenType, String idToken, double notBeforePolicy, String sessionState, String scope) {
+        this.accessToken = accessToken;
+        this.expiresIn = expiresIn;
+        this.refreshExpiresIn = refreshExpiresIn;
+        this.refreshToken = refreshToken;
+        this.tokenType = tokenType;
+        this.idToken = idToken;
+        this.notBeforePolicy = notBeforePolicy;
+        this.sessionState = sessionState;
+        this.scope = scope;
+    }
+
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    public double getExpiresIn() {
+        return expiresIn;
+    }
+
+    public void setExpiresIn(double expiresIn) {
+        this.expiresIn = expiresIn;
+    }
+
+    public double getRefreshExpiresIn() {
+        return refreshExpiresIn;
+    }
+
+    public void setRefreshExpiresIn(double refreshExpiresIn) {
+        this.refreshExpiresIn = refreshExpiresIn;
+    }
+
+    public String getRefreshToken() {
+        return refreshToken;
+    }
+
+    public void setRefreshToken(String refreshToken) {
+        this.refreshToken = refreshToken;
+    }
+
+    public String getTokenType() {
+        return tokenType;
+    }
+
+    public void setTokenType(String tokenType) {
+        this.tokenType = tokenType;
+    }
+
+    public String getIdToken() {
+        return idToken;
+    }
+
+    public void setIdToken(String idToken) {
+        this.idToken = idToken;
+    }
+
+    public double getNotBeforePolicy() {
+        return notBeforePolicy;
+    }
+
+    public void setNotBeforePolicy(double notBeforePolicy) {
+        this.notBeforePolicy = notBeforePolicy;
+    }
+
+    public String getSessionState() {
+        return sessionState;
+    }
+
+    public void setSessionState(String sessionState) {
+        this.sessionState = sessionState;
+    }
+
+    public String getScope() {
+        return scope;
+    }
+
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+}
diff --git a/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/User.java b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/User.java
new file mode 100644
index 0000000..9f27ded
--- /dev/null
+++ b/custos-federated-services-clients/src/main/java/org/apache/custos/federated/services/clients/keycloak/auth/User.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.federated.services.clients.keycloak.auth;
+
+public class User {
+
+    private String sub;
+
+    private String fullName;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String emailAddress;
+
+    private String username;
+
+    public User(String sub, String fullName, String firstName, String lastName, String emailAddress, String username) {
+        this.sub = sub;
+        this.fullName = fullName;
+        this.firstName = firstName;
+        this.lastName = lastName;
+        this.emailAddress = emailAddress;
+        this.username = username;
+    }
+
+    public String getSub() {
+        return sub;
+    }
+
+    public void setSub(String sub) {
+        this.sub = sub;
+    }
+
+    public String getFullName() {
+        return fullName;
+    }
+
+    public void setFullName(String fullName) {
+        this.fullName = fullName;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public String getEmailAddress() {
+        return emailAddress;
+    }
+
+    public void setEmailAddress(String emailAddress) {
+        this.emailAddress = emailAddress;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+}
diff --git a/custos-federated-services-clients/src/main/resources/keycloak-client-truststore.pkcs12 b/custos-federated-services-clients/src/main/resources/keycloak-client-truststore.pkcs12
new file mode 100644
index 0000000..6b84b0f
--- /dev/null
+++ b/custos-federated-services-clients/src/main/resources/keycloak-client-truststore.pkcs12
Binary files differ
diff --git a/custos-integration-core/pom.xml b/custos-integration-core/pom.xml
new file mode 100644
index 0000000..a7f394c
--- /dev/null
+++ b/custos-integration-core/pom.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-integration-core</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceCallback.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceCallback.java
new file mode 100644
index 0000000..8d78f67
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceCallback.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core;
+
+/**
+ * An interface represents callback for async communication
+ */
+public interface ServiceCallback {
+
+
+    void onCompleted(Object obj);
+
+    void onError(ServiceException ex);
+
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceChain.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceChain.java
new file mode 100644
index 0000000..967d15d
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceChain.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * A class represents the set of services that  needs to be invoked to
+ * complete a full operation
+ */
+public final class ServiceChain {
+
+
+private final List<ServiceTask> serviceTasks;
+
+
+   private ServiceChain(ServiceChainBuilder serviceChainBuilder) {
+       this.serviceTasks = serviceChainBuilder.serviceTasks;
+   }
+
+   public void serve(Object data){
+       if (!serviceTasks.isEmpty()) {
+           serviceTasks.get(0).invokeService(data);
+       }
+   }
+
+   public static class ServiceChainBuilder {
+
+       private ServiceCallback serviceCallback;
+       private List<ServiceTask> serviceTasks = new ArrayList();
+       private ServiceTask latestTask;
+
+       private ServiceChainBuilder(ServiceTask firstTask, ServiceCallback serviceCallback) {
+          this.latestTask = firstTask;
+          this.serviceCallback = serviceCallback;
+          this.latestTask.setServiceCallback(serviceCallback);
+          this.serviceTasks.add(this.latestTask);
+       }
+
+
+
+       public ServiceChainBuilder nextTask(ServiceTask serviceTask){
+           this.latestTask.setNextTask(serviceTask);
+           this.latestTask = serviceTask;
+           this.latestTask.setServiceCallback(serviceCallback);
+           this.serviceTasks.add(this.latestTask);
+           return this;
+
+       }
+
+       public ServiceChain build() {
+           ServiceChain serviceChain = new ServiceChain(this);
+           return serviceChain;
+       }
+
+
+    }
+
+    public static ServiceChainBuilder newBuilder(ServiceTask firstTask, ServiceCallback serviceCallback) {
+        return  new ServiceChainBuilder(firstTask, serviceCallback);
+    }
+
+
+
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceException.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceException.java
new file mode 100644
index 0000000..e348f42
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core;
+
+/**
+ * This class wraps exceptions arising in custos message flow and
+ * has a local error code
+ */
+public class ServiceException extends Exception{
+
+    private String code;
+
+    public ServiceException (String message, Throwable cause, String code) {
+        super(message, cause);
+        this.code = code;
+    }
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceTask.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceTask.java
new file mode 100644
index 0000000..4409bf5
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceTask.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core;
+
+/**
+ * Interface represents service task for invoking core services
+ * Service task is bind to a single operation of one client
+ */
+public interface ServiceTask<T, U> {
+
+    void invokeService(T data);
+
+    void  invokeNextTask(U data);
+
+    void setNextTask(ServiceTask serviceTask);
+
+    void setServiceCallback(ServiceCallback serviceCallback);
+
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceTaskImpl.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceTaskImpl.java
new file mode 100644
index 0000000..dda18b7
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/ServiceTaskImpl.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core;
+
+/**
+ *An abstract class of ServiceTaskImpl classes, which implements invokeNextTask logic
+ */
+public abstract class ServiceTaskImpl<T, U> implements ServiceTask<T, U> {
+
+    private ServiceCallback serviceCallback;
+
+    private ServiceTask nextTask;
+
+    private String taskStatus= "Success";
+
+
+
+    public void setServiceCallback(ServiceCallback serviceCallback) {
+        this.serviceCallback = serviceCallback;
+    }
+
+    public ServiceCallback getServiceCallback() {
+        return serviceCallback;
+    }
+
+    public void setNextTask(ServiceTask nextTask) {
+        this.nextTask = nextTask;
+    }
+
+    public ServiceTask getNextTask() {
+        return nextTask;
+    }
+
+    @Override
+    public void invokeNextTask(U output){
+        if (nextTask != null){
+            nextTask.invokeService(output);
+        } else {
+            System.out.println("Calling Parent Callback");
+            serviceCallback.onCompleted(taskStatus);
+        }
+
+    }
+
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/endpoint/TargetEndpoint.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/endpoint/TargetEndpoint.java
new file mode 100644
index 0000000..a43beed
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/endpoint/TargetEndpoint.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core.endpoint;
+
+/**
+ * Represents target endpoint
+ */
+public class TargetEndpoint {
+
+    private String dnsName;
+    private int port;
+
+    public TargetEndpoint(String dnsName, int port) {
+        this.dnsName = dnsName;
+        this.port = port;
+    }
+
+    public String getDnsName() {
+        return dnsName;
+    }
+
+    public void setDnsName(String dnsName) {
+        this.dnsName = dnsName;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/exceptions/MissingParameterException.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/exceptions/MissingParameterException.java
new file mode 100644
index 0000000..504a01a
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/exceptions/MissingParameterException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core.exceptions;
+
+/**
+ * Missing Parameter
+ */
+public class MissingParameterException extends RuntimeException {
+
+   public MissingParameterException(String msg, Throwable e) {
+      super(msg,e);
+   }
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/exceptions/NotAuthorizedException.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/exceptions/NotAuthorizedException.java
new file mode 100644
index 0000000..f61b6cb
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/exceptions/NotAuthorizedException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core.exceptions;
+
+/**
+ * Not authorized exception
+ */
+public class NotAuthorizedException extends RuntimeException {
+
+    public NotAuthorizedException(String msg, Throwable e) {
+        super(msg, e);
+    }
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/interceptor/IntegrationServiceInterceptor.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/interceptor/IntegrationServiceInterceptor.java
new file mode 100644
index 0000000..9d5357b
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/interceptor/IntegrationServiceInterceptor.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core.interceptor;
+
+import io.grpc.Metadata;
+
+public interface IntegrationServiceInterceptor {
+
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg);
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/interceptor/ServiceInterceptor.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/interceptor/ServiceInterceptor.java
new file mode 100644
index 0000000..251044b
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/interceptor/ServiceInterceptor.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core.interceptor;
+
+
+import io.grpc.*;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.core.utils.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.Stack;
+
+/**
+ * This class intercepts incoming requests and forwarding for validation
+ */
+public class ServiceInterceptor implements ServerInterceptor {
+
+    private final Logger LOGGER = LoggerFactory.getLogger(ServiceInterceptor.class);
+
+    private Stack<IntegrationServiceInterceptor> interceptorSet;
+
+    public ServiceInterceptor(Stack<IntegrationServiceInterceptor> integrationServiceInterceptors) {
+        this.interceptorSet = integrationServiceInterceptors;
+    }
+
+
+    @Override
+    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall,
+                                                                 Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
+
+        String fullMethod = serverCall.getMethodDescriptor().getFullMethodName();
+        String methodName = fullMethod.split("/")[1];
+        String serviceName = fullMethod.split("/")[0];
+
+        LOGGER.debug("Calling method : " + serverCall.getMethodDescriptor().getFullMethodName());
+        metadata.put(Metadata.Key.of(Constants.SERVICE_NAME, Metadata.ASCII_STRING_MARSHALLER), serviceName);
+
+        return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(serverCallHandler.startCall(serverCall, metadata)) {
+
+            ReqT resp = null;
+
+            @Override
+            public void onMessage(ReqT message) {
+                try {
+                    Iterator it = interceptorSet.iterator();
+                    while (it.hasNext()) {
+                        IntegrationServiceInterceptor interceptor = (IntegrationServiceInterceptor) it.next();
+                        resp = interceptor.intercept(methodName, metadata, (resp == null) ? message : resp);
+                    }
+                    super.onMessage(resp);
+                } catch (NotAuthorizedException ex) {
+                    String msg = "Error while authorizing method " + methodName + ", " + ex.getMessage();
+                    LOGGER.error(msg);
+                    serverCall.close(Status.UNAUTHENTICATED.withDescription(msg), metadata);
+                } catch (Exception ex) {
+                    String msg = "Error while validating method " + methodName + ", " + ex.getMessage();
+                    LOGGER.error(msg, ex);
+                    serverCall.close(Status.INVALID_ARGUMENT.withDescription(msg), metadata);
+                }
+            }
+
+            @Override
+            public void onHalfClose() {
+                try {
+                    super.onHalfClose();
+                } catch (IllegalStateException e) {
+                    LOGGER.debug(e.getMessage());
+                } catch (Exception e) {
+                    String msg = "Error while validating method " + methodName + ", " + e.getMessage();
+                    LOGGER.error(msg);
+                    serverCall.close(Status.INVALID_ARGUMENT.withDescription(msg), metadata);
+                }
+            }
+
+        };
+
+
+    }
+
+
+}
diff --git a/custos-integration-core/src/main/java/org/apache/custos/integration/core/utils/Constants.java b/custos-integration-core/src/main/java/org/apache/custos/integration/core/utils/Constants.java
new file mode 100644
index 0000000..c99745c
--- /dev/null
+++ b/custos-integration-core/src/main/java/org/apache/custos/integration/core/utils/Constants.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.core.utils;
+
+/**
+ * This is constant class use for integration service
+ */
+public final class Constants {
+
+    public static final String SYSTEM = "SYSTEM";
+
+    public static final String USER_TOKEN = "user-token";
+
+    public static final String TenantId = "tenant-id";
+
+    public static final String X_FORWARDED_FOR = "x-forwarded-for";
+
+    public static final String SERVICE_NAME = "service-name";
+
+}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/Dockerfile b/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/Dockerfile
new file mode 100644
index 0000000..3007968
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/Dockerfile
@@ -0,0 +1,3 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/agent-management-service.pb /data/agent-management-service.pb
+COPY src/main/resources/envoy.yaml  /etc/envoy/envoy.yaml
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/pom.xml b/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/pom.xml
new file mode 100644
index 0000000..4609d5b
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>agent-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>agent-management-service-sidecar</artifactId>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/src/main/resources/agent-management-service.pb b/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/src/main/resources/agent-management-service.pb
new file mode 100644
index 0000000..daeda66
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/src/main/resources/agent-management-service.pb
Binary files differ
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/src/main/resources/envoy.yaml b/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..18347b5
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service-sidecar/src/main/resources/envoy.yaml
@@ -0,0 +1,48 @@
+admin:
+  access_log_path: /tmp/admin_access.log
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+  listeners:
+    - name: main-listener
+      address:
+        socket_address: { address: 0.0.0.0, port_value: 50000 }
+      filter_chains:
+        - filters:
+            - name: envoy.http_connection_manager
+              config:
+                stat_prefix: grpc_json
+                codec_type: AUTO
+                route_config:
+                  name: local_route
+                  virtual_hosts:
+                    - name: local_service
+                      domains: ["*"]
+                      routes:
+                        - match: { prefix: "/", grpc: {} }
+                          route: { cluster: grpc-backend-services, timeout: { seconds: 60 } }
+                http_filters:
+                  - name: envoy.grpc_json_transcoder
+                    config:
+                      proto_descriptor: "/data/agent-management-service.pb"
+                      services: ["org.apache.custos.agent.management.service.AgentManagementService"]
+                      convert_grpc_status: true
+                      print_options:
+                        add_whitespace: true
+                        always_print_primitive_fields: true
+                        always_print_enums_as_ints: false
+                        preserve_proto_field_names: true
+                  - name: envoy.router
+
+  clusters:
+    - name: grpc-backend-services
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: localhost
+            port_value: 7000
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/Dockerfile b/custos-integration-services/agent-management-service-parent/agent-management-service/Dockerfile
new file mode 100644
index 0000000..6457ff8
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/pom.xml b/custos-integration-services/agent-management-service-parent/agent-management-service/pom.xml
new file mode 100644
index 0000000..fc0dfc2
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/pom.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>agent-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>agent-management-service</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>agent-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>iam-admin-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>federated-authentication-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.apache.custos</groupId>-->
+<!--            <artifactId>custos-core-services-commons</artifactId>-->
+<!--            <version>${project.version}</version>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.api.grpc</groupId>
+            <artifactId>proto-google-common-protos</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/.helmignore b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/Chart.yaml b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..9cfffae
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos agent registration service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/NOTES.txt b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/_helpers.tpl b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/deployment.yaml b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..a0957f6
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,78 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+            - name: grpc
+              containerPort: {{ .Values.service.grpcport }}
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: {{ .Values.service.port }}
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+        - name: {{ .Chart.Name }}-envoy-proxy
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.proxy.repository }}:{{ .Values.proxy.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: envoyhttp
+              containerPort: {{ .Values.proxy.port }}
+              protocol: TCP
+            - name: adminhttp
+              containerPort: {{ .Values.proxy.adminport }}
+              protocol: TCP
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/ingress-grpc.yaml b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/ingress-grpc.yaml
new file mode 100644
index 0000000..ebf2b9d
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/ingress-grpc.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: "nginx"
+    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
+    cert-manager.io/cluster-issuer: letsencrypt-production
+  name: ${artifactId}-ingress-grpc
+spec:
+  rules:
+     - host: custos.scigap.org
+       http:
+        paths:
+          - path: /org.apache.custos.agent.management.service.AgentManagementService(/|$)(.*)
+            backend:
+              serviceName: agent-management-service
+              servicePort: grpc
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/ingress.yaml b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..de53722
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
+kind: Ingress
+metadata:
+  name: ${artifactId}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /agent-management/$2
+    cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /agent-management(/|$)(.*)
+            backend:
+              serviceName: agent-management-service
+              servicePort: envoyhttp
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/service.yaml b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..d1e773a
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,33 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  annotations:
+    getambassador.io/config: |
+      ---
+      apiVersion: ambassador/v1
+      kind: Mapping
+      name: tenant-management-service-mapping
+      prefix: /tenant-management/
+      rewrite: ""
+      service: tenant-management-service.custos:50000
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.grpcport }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+    - port: {{ .Values.proxy.port }}
+      targetPort: envoyhttp
+      protocol: TCP
+      name: envoyhttp
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/serviceaccount.yaml b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/tests/test-connection.yaml b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/values.yaml b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..d83557d
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/helm/values.yaml
@@ -0,0 +1,85 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+proxy:
+   repository: apachecustos/agent-management-service-sidecar
+   tag: 1.0-SNAPSHOT
+   port: 50000
+   adminport: 9901
+
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
\ No newline at end of file
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/AgentManagementServiceInitializer.java b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/AgentManagementServiceInitializer.java
new file mode 100644
index 0000000..bc17b84
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/AgentManagementServiceInitializer.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.management;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ClientInterceptor;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.agent.management.interceptors.ClientAuthInterceptorImpl;
+import org.apache.custos.agent.management.interceptors.InputValidator;
+import org.apache.custos.agent.management.interceptors.SuperTenantRestrictedOperationsInterceptorImpl;
+import org.apache.custos.agent.management.interceptors.UserAuthInterceptorImpl;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
+import org.apache.custos.integration.services.commons.interceptors.LoggingInterceptor;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+import java.util.Stack;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "org.apache.custos")
+public class AgentManagementServiceInitializer {
+
+    public static void main(String[] args) {
+        SpringApplication.run(AgentManagementServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        //   Tracing tracing1 =  Tracing.newBuilder().build();
+        return GrpcTracing.create(tracing);
+    }
+
+    //We also create a client-side interceptor and put that in the context, this interceptor can then be injected into gRPC clients and
+    //then applied to the managed channel.
+    @Bean
+    ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newClientInterceptor();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public Stack<IntegrationServiceInterceptor> getInterceptorSet(InputValidator inputValidator,
+                                                                  ClientAuthInterceptorImpl authInterceptor,
+                                                                  UserAuthInterceptorImpl userAuthInterceptor,
+                                                                  SuperTenantRestrictedOperationsInterceptorImpl superTenantRestrictedOperationsInterceptor,
+                                                                  LoggingInterceptor loggingInterceptor) {
+        Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
+        interceptors.add(inputValidator);
+        interceptors.add(authInterceptor);
+        interceptors.add(userAuthInterceptor);
+        interceptors.add(superTenantRestrictedOperationsInterceptor);
+        interceptors.add(loggingInterceptor);
+
+
+        return interceptors;
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(Stack<IntegrationServiceInterceptor> integrationServiceInterceptors) {
+        return new ServiceInterceptor(integrationServiceInterceptors);
+    }
+}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/ClientAuthInterceptorImpl.java b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/ClientAuthInterceptorImpl.java
new file mode 100644
index 0000000..8a3adf1
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/ClientAuthInterceptorImpl.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate confidential client specific authorization.
+ * Methods which authenticates based only on client are implemented here.
+ */
+@Component
+public class ClientAuthInterceptorImpl extends AuthInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+    @Autowired
+    public ClientAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT reqT) {
+
+      return reqT;
+    }
+
+}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/InputValidator.java b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/InputValidator.java
new file mode 100644
index 0000000..495b9fb
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/InputValidator.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.management.interceptors;
+
+
+import io.grpc.Metadata;
+import org.apache.custos.integration.core.exceptions.MissingParameterException;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class validates the  request input parameters
+ */
+@Component
+public class InputValidator implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param body
+     * @return
+     */
+    private void validate(String methodName, Object body, Metadata headers) {
+
+        validationAuthorizationHeader(headers);
+    }
+
+
+    private boolean validationAuthorizationHeader(Metadata headers) {
+        if (headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER)) == null
+                || headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)) == null) {
+            throw new MissingParameterException("authorization header not available", null);
+        }
+
+        return true;
+    }
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        validate(method, msg, headers);
+        return msg;
+    }
+}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/SuperTenantRestrictedOperationsInterceptorImpl.java b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/SuperTenantRestrictedOperationsInterceptorImpl.java
new file mode 100644
index 0000000..d1f2a4e
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/SuperTenantRestrictedOperationsInterceptorImpl.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.iam.service.GetAllResources;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SuperTenantRestrictedOperationsInterceptorImpl extends AuthInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SuperTenantRestrictedOperationsInterceptorImpl.class);
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+
+    public SuperTenantRestrictedOperationsInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient,
+                                                          TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+
+        if (method.equals("synchronizeAgentDBs")) {
+            AuthClaim claim = null;
+            try {
+                claim = authorizeUsingUserToken(headers);
+            } catch (Exception ex) {
+                LOGGER.error(" Authorizing error " + ex.getMessage());
+                throw new NotAuthorizedException("Request is not authorized", ex);
+            }
+            if (claim == null || !claim.isSuperTenant() || !claim.isAdmin()) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+        }
+
+        return msg;
+    }
+
+
+}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/UserAuthInterceptorImpl.java b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/UserAuthInterceptorImpl.java
new file mode 100644
index 0000000..d7ece06
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/interceptors/UserAuthInterceptorImpl.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.agent.management.service.AgentSearchRequest;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.credential.store.service.CredentialMetadata;
+import org.apache.custos.credential.store.service.GetCredentialRequest;
+import org.apache.custos.credential.store.service.Type;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate user specific authorization
+ * Methods authenticates users access tokens are implemented here
+ */
+@Component
+public class UserAuthInterceptorImpl extends AuthInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+    @Autowired
+    public UserAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        String token = getToken(headers);
+        AuthClaim claim = authorizeUsingUserToken(headers);
+        long tenantId = claim.getTenantId();
+
+        if (claim == null) {
+            throw new NotAuthorizedException("Request is not authorized", null);
+        }
+
+        if (!method.equals("enableAgents")) {
+
+            GetCredentialRequest request = GetCredentialRequest
+                    .newBuilder()
+                    .setType(Type.AGENT_CLIENT)
+                    .setOwnerId(tenantId)
+                    .build();
+
+            CredentialMetadata metadata = this.credentialStoreServiceClient.getCredential(request);
+            if (metadata == null || metadata.getId().equals("")) {
+                throw new NotAuthorizedException("Agent creation is not enabled", null);
+            }
+
+        }
+
+        if (method.equals("enableAgents") || method.equals("configureAgentClient")) {
+
+            return (ReqT) ((AgentClientMetadata) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .setAccessToken(token)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+        } else if (method.equals("registerAndEnableAgent")) {
+
+
+            return (ReqT) ((RegisterUserRequest) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .setAccessToken(token)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+        } else if (method.equals("getAgent") || method.equals("deleteAgent") || method.equals("disableAgent") ||
+                method.equals("enableAgent")) {
+
+
+            return (ReqT) ((AgentSearchRequest) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .setAccessToken(token)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+        } else if (method.equals("addAgentAttributes")) {
+
+            return (ReqT) ((AddUserAttributesRequest) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .setAccessToken(token)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+        } else if (method.equals("deleteAgentAttributes")) {
+
+            return (ReqT) ((DeleteUserAttributeRequest) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .setAccessToken(token)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+        } else if (method.equals("addRolesToAgent")) {
+
+            return (ReqT) ((AddUserRolesRequest) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .setAccessToken(token)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+        } else if (method.equals("deleteRolesFromAgent")) {
+
+            return (ReqT) ((DeleteUserRolesRequest) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .setAccessToken(token)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+        } else if (method.equals("addProtocolMapper")) {
+
+            GetCredentialRequest request = GetCredentialRequest
+                    .newBuilder()
+                    .setType(Type.AGENT_CLIENT)
+                    .setOwnerId(tenantId)
+                    .build();
+
+            CredentialMetadata metadata = this.credentialStoreServiceClient.getCredential(request);
+            if (metadata == null || metadata.getId().equals("")) {
+                throw new NotAuthorizedException("Agent creation is not enabled", null);
+            }
+
+            return (ReqT) ((AddProtocolMapperRequest) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .setClientId(metadata.getId())
+                    .build();
+
+        } else if (method.equals("addRolesToClient")) {
+            GetCredentialRequest request = GetCredentialRequest
+                    .newBuilder()
+                    .setType(Type.AGENT_CLIENT)
+                    .setOwnerId(tenantId)
+                    .build();
+
+            CredentialMetadata metadata = this.credentialStoreServiceClient.getCredential(request);
+            if (metadata == null || metadata.getId().equals("")) {
+                throw new NotAuthorizedException("Agent creation is not enabled", null);
+            }
+
+            return (ReqT) ((AddRolesRequest) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .build();
+
+        } else if (method.equals("getAllAgents")) {
+            GetCredentialRequest request = GetCredentialRequest
+                    .newBuilder()
+                    .setType(Type.AGENT_CLIENT)
+                    .setOwnerId(tenantId)
+                    .build();
+
+            CredentialMetadata metadata = this.credentialStoreServiceClient.getCredential(request);
+            if (metadata == null || metadata.getId().equals("")) {
+                throw new NotAuthorizedException("Agent creation is not enabled", null);
+            }
+
+            return (ReqT) ((GetAllResources) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .setClientId(metadata.getId())
+                    .build();
+
+        }
+
+        return msg;
+    }
+
+
+}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/service/AgentManagementService.java b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/service/AgentManagementService.java
new file mode 100644
index 0000000..342bbbe
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/java/org/apache/custos/agent/management/service/AgentManagementService.java
@@ -0,0 +1,837 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.agent.management.service;
+
+import io.grpc.Context;
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.agent.profile.client.AgentProfileClient;
+import org.apache.custos.agent.profile.service.Agent;
+import org.apache.custos.agent.profile.service.AgentAttribute;
+import org.apache.custos.agent.profile.service.AgentRequest;
+import org.apache.custos.agent.profile.service.AgentStatus;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.credential.store.service.CredentialMetadata;
+import org.apache.custos.credential.store.service.GetCredentialRequest;
+import org.apache.custos.credential.store.service.Type;
+import org.apache.custos.iam.admin.client.IamAdminServiceClient;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.tenant.profile.service.GetTenantRequest;
+import org.apache.custos.tenant.profile.service.GetTenantResponse;
+import org.apache.custos.tenant.profile.service.Tenant;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@GRpcService
+public class AgentManagementService extends org.apache.custos.agent.management.service.AgentManagementServiceGrpc.AgentManagementServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AgentManagementService.class);
+
+    @Autowired
+    private AgentProfileClient agentProfileClient;
+
+    @Autowired
+    private IamAdminServiceClient iamAdminServiceClient;
+
+    @Autowired
+    private IdentityClient identityClient;
+
+    @Autowired
+    private TenantProfileClient tenantProfileClient;
+
+    @Autowired
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+
+    private static final String AGENT_CLIENT = "agent-client";
+
+    private static final String CUSTOS_REALM_AGENT = "custos-realm-agent";
+
+
+    @Override
+    public void enableAgents(AgentClientMetadata request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            LOGGER.debug("Request received to enable agent " + request.getTenantId());
+
+
+            GetTenantRequest tenantRequest = GetTenantRequest
+                    .newBuilder()
+                    .setTenantId(request.getTenantId()).build();
+
+            GetTenantResponse response = tenantProfileClient.getTenant(tenantRequest);
+
+            Tenant tenant = response.getTenant();
+
+            if (tenant == null || tenant.getTenantId() == 0) {
+                String msg = "Tenant not found  for " + request.getTenantId();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            List<String> redirectURIs = new ArrayList<>();
+            String redirectURI = tenant.getClientUri() + "/agent/callback";
+            redirectURIs.add(redirectURI);
+
+            request = request.toBuilder()
+                    .setTenantURL(tenant.getClientUri())
+                    .addAllRedirectURIs(redirectURIs)
+                    .setClientName(AGENT_CLIENT)
+                    .build();
+
+            GetCredentialRequest credentialRequest = GetCredentialRequest
+                    .newBuilder()
+                    .setType(Type.AGENT_CLIENT)
+                    .setOwnerId(request.getTenantId())
+                    .build();
+
+            CredentialMetadata credentialMetadata = this.credentialStoreServiceClient.getCredential(credentialRequest);
+            if (credentialMetadata != null && !credentialMetadata.getId().equals("")) {
+                OperationStatus operationStatus = OperationStatus.newBuilder().setStatus(true).build();
+                responseObserver.onNext(operationStatus);
+                responseObserver.onCompleted();
+                return;
+            }
+
+
+            SetUpTenantResponse setUpTenantResponse = iamAdminServiceClient.createAgentClient(request);
+
+
+            if (setUpTenantResponse == null || setUpTenantResponse.getClientId().equals("") ||
+                    setUpTenantResponse.getClientSecret().equals("")) {
+                String msg = "Agent activation failed for tenant " + request.getTenantId();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            CredentialMetadata metadata = CredentialMetadata.newBuilder().
+                    setId(setUpTenantResponse.getClientId())
+                    .setSecret(setUpTenantResponse.getClientSecret())
+                    .setOwnerId(request.getTenantId())
+                    .setType(Type.AGENT_CLIENT)
+                    .build();
+            org.apache.custos.credential.store.service.OperationStatus status = credentialStoreServiceClient.putCredential(metadata);
+
+            OperationStatus operationStatus = OperationStatus.newBuilder().setStatus(status.getState()).build();
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at enableAgents " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void registerAndEnableAgent(RegisterUserRequest request, StreamObserver<org.apache.custos.agent.management.service.AgentRegistrationResponse> responseObserver) {
+        try {
+
+            LOGGER.debug("Request received to registerAndEnableAgent for tenant " + request.getTenantId() +
+                    " for agent " + request.getUser().getId());
+
+            UserSearchMetadata metadata = UserSearchMetadata.newBuilder().setId(request.getUser().getId()).build();
+
+            UserSearchRequest userSearchRequest = UserSearchRequest.
+                    newBuilder().setUser(metadata).
+                    setTenantId(request.getTenantId())
+                    .setAccessToken(request.getAccessToken()).build();
+
+            OperationStatus status = iamAdminServiceClient.isAgentNameAvailable(userSearchRequest);
+
+
+            if (status.getStatus()) {
+
+
+                CredentialMetadata credentialMetadata = CredentialMetadata.newBuilder()
+                        .setOwnerId(request.getTenantId())
+                        .setId(request.getUser().getId())
+                        .build();
+
+                CredentialMetadata agentCredential = credentialStoreServiceClient.createAgentCredential(credentialMetadata);
+
+                UserRepresentation representation = request.getUser();
+                representation = representation.toBuilder().setPassword(agentCredential.getInternalSec()).build();
+
+
+                List<UserAttribute> attributeList = request.toBuilder().getUser().getAttributesList();
+                List<UserAttribute> newAtrList = new ArrayList<>();
+                if (attributeList != null && !attributeList.isEmpty()) {
+                    newAtrList.addAll(attributeList);
+
+                }
+
+                UserAttribute attribute = UserAttribute.newBuilder()
+                        .setKey(CUSTOS_REALM_AGENT).addValues("true").build();
+                newAtrList.add(attribute);
+                representation = representation.toBuilder().addAllAttributes(newAtrList).build();
+
+                request = request.toBuilder().setUser(representation).setClientId(AGENT_CLIENT).build();
+
+                RegisterUserResponse response = iamAdminServiceClient.registerAndEnableAgent(request);
+
+                if (response.getIsRegistered()) {
+
+                    Agent agent = Agent.newBuilder()
+                            .setId(representation.getId().toLowerCase())
+                            .setStatus(AgentStatus.ENABLED)
+                            .build();
+
+                    if (representation.getRealmRolesList() != null && !representation.getRealmRolesList().isEmpty()) {
+                        agent = agent.toBuilder().addAllRoles(representation.getRealmRolesList()).build();
+
+                    }
+
+                    if (representation.getClientRolesList() != null && !representation.getClientRolesList().isEmpty()) {
+                        agent = agent.toBuilder().addAllAgentClientRoles(representation.getClientRolesList()).build();
+                    }
+
+                    if (representation.getAttributesList() != null && !representation.getAttributesList().isEmpty()) {
+                        List<AgentAttribute> agentAttributes = new ArrayList<>();
+                        representation.getAttributesList().forEach(atr -> {
+                            AgentAttribute agentAttribute = AgentAttribute
+                                    .newBuilder()
+                                    .setKey(atr.getKey())
+                                    .addAllValue(atr.getValuesList())
+                                    .build();
+                            agentAttributes.add(agentAttribute);
+
+                        });
+
+                        agent = agent.toBuilder().addAllAttributes(agentAttributes).build();
+                    }
+
+
+                    AgentRequest agentRequest = AgentRequest.newBuilder()
+                            .setTenantId(request.getTenantId())
+                            .setAgent(agent)
+                            .build();
+                    agentProfileClient.createAgent(agentRequest);
+
+                    org.apache.custos.agent.management.service.AgentRegistrationResponse registrationResponse =
+                            org.apache.custos.agent.management.service.AgentRegistrationResponse
+                                    .newBuilder()
+                                    .setId(request.getUser().getId())
+                                    .setSecret(agentCredential.getSecret())
+                                    .build();
+
+                    responseObserver.onNext(registrationResponse);
+                    responseObserver.onCompleted();
+
+                } else {
+                    String msg = "Agent name not registered ";
+                    LOGGER.error(msg);
+                    responseObserver.onError(Status.INTERNAL.
+                            withDescription(msg).asRuntimeException());
+                }
+
+            } else {
+                String msg = "Agent name is not valid ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.ALREADY_EXISTS.
+                        withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at registerAndEnableAgent " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void configureAgentClient(AgentClientMetadata request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            LOGGER.debug("Request received to configure agent client" + request.getTenantId());
+
+            GetTenantRequest tenantRequest = GetTenantRequest
+                    .newBuilder()
+                    .setTenantId(request.getTenantId()).build();
+
+            GetTenantResponse response = tenantProfileClient.getTenant(tenantRequest);
+
+            Tenant tenant = response.getTenant();
+
+            if (tenant == null || tenant.getTenantId() == 0) {
+                String msg = "Tenant not found  for " + request.getTenantId();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                return;
+            }
+
+            request = request.toBuilder().setClientName(AGENT_CLIENT).build();
+
+            OperationStatus status = iamAdminServiceClient.configureAgentClient(request);
+
+            OperationStatus operationStatus = OperationStatus.newBuilder().setStatus(status.getStatus()).build();
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at configureAgentClient " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void addRolesToClient(AddRolesRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            LOGGER.debug("Request received to add agent client roles" + request.getTenantId());
+
+            request = request.toBuilder()
+                    .setClientId(AGENT_CLIENT)
+                    .setClientLevel(true)
+                    .build();
+
+            iamAdminServiceClient.addRolesToTenant(request);
+
+            OperationStatus operationStatus = OperationStatus.newBuilder().setStatus(true).build();
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at addRolesToClient " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void getAgent(AgentSearchRequest request, StreamObserver<org.apache.custos.iam.service.Agent> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAgent " + request.getTenantId());
+
+            UserSearchMetadata metadata = UserSearchMetadata.newBuilder().setId(request.getId()).build();
+
+            UserSearchRequest searchRequest = UserSearchRequest
+                    .newBuilder()
+                    .setUser(metadata)
+                    .setTenantId(request.getTenantId())
+                    .setAccessToken(request.getAccessToken())
+                    .build();
+
+            org.apache.custos.iam.service.Agent agent = iamAdminServiceClient.getAgent(searchRequest);
+            List<UserAttribute> attributeList = agent.getAttributesList();
+            List<UserAttribute> userAttributes = new ArrayList<>();
+            for (UserAttribute attribute : attributeList) {
+                if (!attribute.getKey().trim().equals(CUSTOS_REALM_AGENT)) {
+                    userAttributes.add(attribute);
+                }
+            }
+            agent = agent.toBuilder().clearAttributes().addAllAttributes(userAttributes).build();
+
+            responseObserver.onNext(agent);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAgent " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void deleteAgent(AgentSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            LOGGER.debug("Request received to deleteAgent " + request.getTenantId());
+
+            UserSearchMetadata metadata = UserSearchMetadata.newBuilder().setId(request.getId()).build();
+
+            UserSearchRequest searchRequest = UserSearchRequest
+                    .newBuilder()
+                    .setUser(metadata)
+                    .setTenantId(request.getTenantId())
+                    .setAccessToken(request.getAccessToken())
+                    .build();
+
+            OperationStatus status = iamAdminServiceClient.deleteAgent(searchRequest);
+
+            if (status.getStatus()) {
+
+                CredentialMetadata credentialMetadata = CredentialMetadata.newBuilder()
+                        .setOwnerId(request.getTenantId())
+                        .setId(request.getId())
+                        .build();
+
+                credentialStoreServiceClient.deleteAgentCredential(credentialMetadata);
+
+                Agent agent = Agent.newBuilder().setId(request.getId().toLowerCase()).build();
+
+                AgentRequest agentRequest = AgentRequest.newBuilder().setTenantId(request.getTenantId())
+                        .setAgent(agent).build();
+                agentProfileClient.deleteAgent(agentRequest);
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+
+            } else {
+                String msg = "Error occurred at delete Agent at IAM Server ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAgent " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void disableAgent(AgentSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            LOGGER.debug("Request received to disableAgent " + request.getTenantId());
+
+            UserSearchMetadata metadata = UserSearchMetadata.newBuilder().setId(request.getId()).build();
+
+            UserSearchRequest searchRequest = UserSearchRequest
+                    .newBuilder()
+                    .setUser(metadata)
+                    .setTenantId(request.getTenantId())
+                    .setAccessToken(request.getAccessToken())
+                    .build();
+
+            OperationStatus status = iamAdminServiceClient.disableAgent(searchRequest);
+
+            if (status.getStatus()) {
+
+                org.apache.custos.iam.service.Agent agent = iamAdminServiceClient.getAgent(searchRequest);
+
+
+                Agent agentProfile = getAgentProfile(agent);
+
+                AgentRequest agentRequest = AgentRequest.newBuilder().setTenantId(request.getTenantId())
+                        .setAgent(agentProfile).build();
+                agentProfileClient.updateAgent(agentRequest);
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+            } else {
+                String msg = "Error occurred at disable Agent at IAM Server ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at disableAgent " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void addAgentAttributes(AddUserAttributesRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            LOGGER.debug("Request received to addAgentAttributes " + request.getTenantId());
+
+            OperationStatus status = iamAdminServiceClient.addAgentAttributes(request);
+
+            if (status.getStatus()) {
+
+                for (String agent : request.getAgentsList()) {
+
+                    UserSearchMetadata metadata = UserSearchMetadata.newBuilder().setId(agent).build();
+
+                    UserSearchRequest searchRequest = UserSearchRequest
+                            .newBuilder()
+                            .setUser(metadata)
+                            .setTenantId(request.getTenantId())
+                            .setAccessToken(request.getAccessToken())
+                            .build();
+
+                    org.apache.custos.iam.service.Agent iamAgent = iamAdminServiceClient.getAgent(searchRequest);
+
+                    Agent agentProfile = getAgentProfile(iamAgent);
+                    AgentRequest agentRequest = AgentRequest.newBuilder().setTenantId(request.getTenantId())
+                            .setAgent(agentProfile).build();
+                    agentProfileClient.updateAgent(agentRequest);
+                }
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+            } else {
+                String msg = "Error occurred at addAgentAttributes at IAM Server ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at addAgentAttributes " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+
+    }
+
+
+    @Override
+    public void deleteAgentAttributes(DeleteUserAttributeRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteAgentAttributes " + request.getTenantId());
+
+            OperationStatus status = iamAdminServiceClient.deleteAgentAttributes(request);
+
+            if (status.getStatus()) {
+
+                for (String agent : request.getAgentsList()) {
+
+                    UserSearchMetadata metadata = UserSearchMetadata.newBuilder().setId(agent).build();
+
+                    UserSearchRequest searchRequest = UserSearchRequest
+                            .newBuilder()
+                            .setUser(metadata)
+                            .setTenantId(request.getTenantId())
+                            .setAccessToken(request.getAccessToken())
+                            .build();
+
+                    org.apache.custos.iam.service.Agent iamAgent = iamAdminServiceClient.getAgent(searchRequest);
+                    Agent agentProfile = getAgentProfile(iamAgent);
+
+                    AgentRequest agentRequest = AgentRequest.newBuilder().setTenantId(request.getTenantId())
+                            .setAgent(agentProfile).build();
+                    agentProfileClient.updateAgent(agentRequest);
+                }
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+            } else {
+                String msg = "Error occurred at deleteAgentAttributes at IAM Server ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at deleteAgentAttributes " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void addRolesToAgent(AddUserRolesRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteAgentAttributes " + request.getTenantId());
+            request = request.toBuilder().setClientId(AGENT_CLIENT).build();
+
+            OperationStatus status = iamAdminServiceClient.addRolesToAgent(request);
+
+            if (status.getStatus()) {
+
+                for (String agent : request.getAgentsList()) {
+
+                    UserSearchMetadata metadata = UserSearchMetadata.newBuilder().setId(agent).build();
+
+                    UserSearchRequest searchRequest = UserSearchRequest
+                            .newBuilder()
+                            .setUser(metadata)
+                            .setTenantId(request.getTenantId())
+                            .setAccessToken(request.getAccessToken())
+                            .build();
+
+                    org.apache.custos.iam.service.Agent iamAgent = iamAdminServiceClient.getAgent(searchRequest);
+
+                    Agent agentProfile = getAgentProfile(iamAgent);
+
+                    AgentRequest agentRequest = AgentRequest.newBuilder().setTenantId(request.getTenantId())
+                            .setAgent(agentProfile).build();
+                    agentProfileClient.updateAgent(agentRequest);
+                }
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+            } else {
+                String msg = "Error occurred at addRolesToAgent at IAM Server ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at addRolesToAgent " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void deleteRolesFromAgent(DeleteUserRolesRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteAgentAttributes " + request.getTenantId());
+
+            request = request.toBuilder().setClientId(AGENT_CLIENT).build();
+
+
+            OperationStatus status = iamAdminServiceClient.deleteAgentRoles(request);
+
+            if (status.getStatus()) {
+
+
+                UserSearchMetadata metadata = UserSearchMetadata.newBuilder().setId(request.getId()).build();
+
+                UserSearchRequest searchRequest = UserSearchRequest
+                        .newBuilder()
+                        .setUser(metadata)
+                        .setTenantId(request.getTenantId())
+                        .setAccessToken(request.getAccessToken())
+                        .build();
+
+                org.apache.custos.iam.service.Agent iamAgent = iamAdminServiceClient.getAgent(searchRequest);
+
+                Agent agentProfile = getAgentProfile(iamAgent);
+
+                AgentRequest agentRequest = AgentRequest.newBuilder().setTenantId(request.getTenantId())
+                        .setAgent(agentProfile).build();
+                agentProfileClient.updateAgent(agentRequest);
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+            } else {
+                String msg = "Error occurred at deleteRolesFromAgent at IAM Server ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at deleteRolesFromAgent " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void enableAgent(AgentSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to enableAgent " + request.getTenantId());
+
+            UserSearchMetadata metadata = UserSearchMetadata.newBuilder().setId(request.getId()).build();
+
+            UserSearchRequest searchRequest = UserSearchRequest
+                    .newBuilder()
+                    .setUser(metadata)
+                    .setTenantId(request.getTenantId())
+                    .setAccessToken(request.getAccessToken())
+                    .build();
+
+            OperationStatus status = iamAdminServiceClient.enableAgent(searchRequest);
+
+            if (status.getStatus()) {
+
+                org.apache.custos.iam.service.Agent agent = iamAdminServiceClient.getAgent(searchRequest);
+
+
+                Agent agentProfile = getAgentProfile(agent);
+
+                AgentRequest agentRequest = AgentRequest.newBuilder().setTenantId(request.getTenantId())
+                        .setAgent(agentProfile).build();
+                agentProfileClient.updateAgent(agentRequest);
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+
+            } else {
+                String msg = "Error occurred at disable Agent at IAM Server ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at disableAgent " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void addProtocolMapper(AddProtocolMapperRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            OperationStatus allRoles = iamAdminServiceClient.addProtocolMapper(request);
+
+            responseObserver.onNext(allRoles);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at addProtocolMapper " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getAllAgents(GetAllResources request, StreamObserver<GetAllResourcesResponse> responseObserver) {
+        try {
+            GetAllResources resources = request.toBuilder().setResourceType(ResourceTypes.AGENT).build();
+            GetAllResourcesResponse allRoles = iamAdminServiceClient.getAllResources(resources);
+
+            responseObserver.onNext(allRoles);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAllAgents in tenant " + request.getTenantId() + "reason :" + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void synchronizeAgentDBs(SynchronizeAgentDBRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            Context ctx = Context.current().fork();
+            ctx.run(() -> {
+                GetAllResources resources = GetAllResources
+                        .newBuilder()
+                        .setClientId(request.getClientId())
+                        .setTenantId(request.getTenantId())
+                        .setResourceType(ResourceTypes.AGENT)
+                        .build();
+                GetAllResourcesResponse response = iamAdminServiceClient.getAllResources(resources);
+
+                if (response != null && response.getAgentsList() != null && !response.getAgentsList().isEmpty()) {
+
+                    for (org.apache.custos.iam.service.Agent agent : response.getAgentsList()) {
+
+                        Agent profile = getAgentProfile(agent);
+
+                        AgentRequest agentRequest = AgentRequest.newBuilder().setTenantId(request.getTenantId())
+                                .setAgent(profile).build();
+                        Agent exAgent = agentProfileClient.getAgent(agentRequest);
+
+
+                        if (exAgent != null && exAgent.getId() != null && !exAgent.getId().equals("")) {
+                            agentProfileClient.updateAgent(agentRequest);
+                        } else {
+                            agentProfileClient.createAgent(agentRequest);
+                        }
+                    }
+                }
+
+                OperationStatus status = OperationStatus.newBuilder().setStatus(true).build();
+
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+            });
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at synchronizeAgentDBs " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    private Agent getAgentProfile(org.apache.custos.iam.service.Agent iamAgent) {
+        Agent.Builder agentProfile = Agent.newBuilder()
+                .setId(iamAgent.getId().toLowerCase())
+                .setStatus(iamAgent.getIsEnabled() ? AgentStatus.ENABLED : AgentStatus.DISABLED);
+
+        if (!iamAgent.getRealmRolesList().isEmpty()) {
+            agentProfile = agentProfile.addAllRoles(iamAgent.getRealmRolesList());
+        }
+
+        if (!iamAgent.getClientRolesList().isEmpty()) {
+            agentProfile = agentProfile.addAllAgentClientRoles(iamAgent.getClientRolesList());
+        }
+
+
+        for (UserAttribute atr : iamAgent.getAttributesList()) {
+
+            AgentAttribute agentAttribute = AgentAttribute.newBuilder()
+                    .setKey(atr.getKey())
+                    .addAllValue(atr.getValuesList())
+                    .build();
+
+            agentProfile = agentProfile.addAttributes(agentAttribute);
+
+        }
+        return agentProfile.build();
+
+    }
+
+
+}
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/proto/AgentManagementService.proto b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/proto/AgentManagementService.proto
new file mode 100644
index 0000000..6dd59e6
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/proto/AgentManagementService.proto
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.agent.management.service;
+
+import "google/api/annotations.proto";
+import "google/rpc/error_details.proto";
+import "google/protobuf/empty.proto";
+import "IamAdminService.proto";
+
+
+message AgentSearchRequest {
+    int64 tenantId = 2;
+    string accessToken = 3;
+    string clientId = 4;
+    string clientSec = 5;
+    string performedBy = 6;
+    string id = 7;
+}
+
+message AgentRegistrationResponse {
+    string id = 1;
+    string secret = 2;
+}
+
+message SynchronizeAgentDBRequest {
+    int64 tenantId = 2;
+    string clientId = 4;
+}
+
+
+service AgentManagementService {
+
+    rpc enableAgents (org.apache.custos.iam.service.AgentClientMetadata) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/agent-management/v1.0.0/enable"
+         };
+    }
+    rpc configureAgentClient (org.apache.custos.iam.service.AgentClientMetadata) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/agent-management/v1.0.0/token/configuration"
+         };
+    }
+
+
+    rpc addRolesToClient (org.apache.custos.iam.service.AddRolesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/agent-management/v1.0.0/roles"
+         };
+    }
+
+    rpc registerAndEnableAgent (org.apache.custos.iam.service.RegisterUserRequest) returns (AgentRegistrationResponse) {
+        option (google.api.http) = {
+           post: "/agent-management/v1.0.0/agent"
+           body: "user"
+         };
+    }
+
+    rpc getAgent (AgentSearchRequest) returns (org.apache.custos.iam.service.Agent) {
+        option (google.api.http) = {
+           get: "/agent-management/v1.0.0/agent/{id}"
+         };
+    }
+
+    rpc deleteAgent (AgentSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           delete: "/agent-management/v1.0.0/agent/{id}"
+         };
+    }
+    rpc disableAgent (AgentSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/agent-management/v1.0.0/agent/deactivation/{id}"
+         };
+
+    }
+
+    rpc enableAgent (AgentSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/agent-management/v1.0.0/agent/activation/{id}"
+         };
+
+    }
+
+    rpc addAgentAttributes (org.apache.custos.iam.service.AddUserAttributesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/agent-management/v1.0.0/agent/attributes"
+         };
+    }
+    rpc deleteAgentAttributes (org.apache.custos.iam.service.DeleteUserAttributeRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           delete: "/agent-management/v1.0.0/agent/attributes"
+         };
+    }
+    rpc addRolesToAgent (org.apache.custos.iam.service.AddUserRolesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/agent-management/v1.0.0/agent/roles"
+         };
+    }
+    rpc deleteRolesFromAgent (org.apache.custos.iam.service.DeleteUserRolesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           delete: "/agent-management/v1.0.0/agent/roles"
+         };
+    }
+
+    rpc addProtocolMapper (org.apache.custos.iam.service.AddProtocolMapperRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/agent-management/v1.0.0/protocol/mapper"
+        };
+    }
+
+    rpc getAllAgents (org.apache.custos.iam.service.GetAllResources) returns (org.apache.custos.iam.service.GetAllResourcesResponse) {
+        option (google.api.http) = {
+           get: "/agent-management/v1.0.0/agents"
+        };
+    }
+
+     rpc synchronizeAgentDBs (SynchronizeAgentDBRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+         option (google.api.http) = {
+           post: "/agent-management/v1.0.0/db/synchronize"
+        };
+      }
+
+
+}
+
+
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/resources/application.properties b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/resources/application.properties
new file mode 100644
index 0000000..46960c9
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/resources/application.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+server.port=8080
+grpc.port=7000
+spring.application.name=agentManagementService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
diff --git a/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/resources/bootstrap.properties b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/agent-management-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default
diff --git a/custos-integration-services/agent-management-service-parent/pom.xml b/custos-integration-services/agent-management-service-parent/pom.xml
new file mode 100644
index 0000000..957d7c8
--- /dev/null
+++ b/custos-integration-services/agent-management-service-parent/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>agent-management-service-parent</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>agent-management-service</module>
+        <module>agent-management-service-sidecar</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/custos-integration-services-commons/pom.xml b/custos-integration-services/custos-integration-services-commons/pom.xml
new file mode 100644
index 0000000..bded007
--- /dev/null
+++ b/custos-integration-services/custos-integration-services-commons/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-integration-services-commons</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>iam-admin-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-logging-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java
new file mode 100644
index 0000000..94eab51
--- /dev/null
+++ b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java
@@ -0,0 +1,435 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.services.commons.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.credential.store.service.*;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.identity.service.Claim;
+import org.apache.custos.identity.service.GetUserManagementSATokenRequest;
+import org.apache.custos.identity.service.IsAuthenticateResponse;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.utils.Constants;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.tenant.profile.service.GetTenantRequest;
+import org.apache.custos.tenant.profile.service.GetTenantResponse;
+import org.apache.custos.tenant.profile.service.Tenant;
+import org.apache.custos.tenant.profile.service.TenantStatus;
+import org.apache.tomcat.util.bcel.Const;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Responsible for managing auth flow
+ */
+public abstract class AuthInterceptor implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AuthInterceptor.class);
+
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+    private TenantProfileClient tenantProfileClient;
+
+    private IdentityClient identityClient;
+
+
+    public AuthInterceptor(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+        this.tenantProfileClient = tenantProfileClient;
+        this.identityClient = identityClient;
+    }
+
+    public AuthClaim authorize(Metadata headers) {
+        try {
+            String formattedToken = getToken(headers);
+
+            if (formattedToken == null) {
+                return null;
+            }
+            return authorize(formattedToken);
+        } catch (Exception ex) {
+            throw new NotAuthorizedException("Wrong credentials " + ex.getMessage(), ex);
+        }
+
+    }
+
+    public AuthClaim authorize(String formattedToken) {
+        try {
+            TokenRequest request = TokenRequest
+                    .newBuilder()
+                    .setToken(formattedToken)
+                    .build();
+            GetAllCredentialsResponse response = credentialStoreServiceClient.getAllCredentialFromToken(request);
+            return getAuthClaim(response);
+        } catch (Exception ex) {
+            throw new NotAuthorizedException("Wrong credentials " + ex.getMessage(), ex);
+        }
+
+    }
+
+
+    public AuthClaim authorizeUsingUserToken(Metadata headers) {
+
+        try {
+            String formattedToken = getToken(headers);
+
+            if (formattedToken == null) {
+                return null;
+            }
+
+            return authorizeUsingUserToken(formattedToken);
+        } catch (Exception ex) {
+            throw new NotAuthorizedException("Wrong credentials " + ex.getMessage(), ex);
+        }
+
+    }
+
+    public AuthClaim authorizeUsingUserToken(String formattedToken) {
+
+        try {
+
+            TokenRequest request = TokenRequest
+                    .newBuilder()
+                    .setToken(formattedToken)
+                    .build();
+
+            GetAllCredentialsResponse response = credentialStoreServiceClient.getAllCredentialsFromJWTToken(request);
+
+            AuthClaim claim = getAuthClaim(response);
+
+            if (claim != null) {
+
+                Claim userNameClaim = Claim.newBuilder()
+                        .setKey("username")
+                        .setValue(claim.getUsername()).build();
+
+                Claim tenantClaim = Claim.newBuilder()
+                        .setKey("tenantId")
+                        .setValue(String.valueOf(claim.getTenantId()))
+                        .build();
+
+
+                List<Claim> claimList = new ArrayList<>();
+                claimList.add(userNameClaim);
+                claimList.add(tenantClaim);
+
+
+                AuthToken token = AuthToken.newBuilder().
+                        setAccessToken(formattedToken)
+                        .addAllClaims(claimList)
+                        .build();
+
+
+                IsAuthenticateResponse isAuthenticateResponse = identityClient.isAuthenticated(token);
+                if (isAuthenticateResponse.getAuthenticated()) {
+                    return claim;
+                }
+            }
+
+            return null;
+        } catch (Exception ex) {
+            throw new NotAuthorizedException("Wrong credentials " + ex.getMessage(), ex);
+        }
+
+    }
+
+
+    public AuthClaim authorizeUsingAgentBasicToken(Metadata headers, String parentId) {
+
+        try {
+            String formattedToken = getToken(headers);
+
+            if (formattedToken == null) {
+                return null;
+            }
+
+            TokenRequest request = TokenRequest
+                    .newBuilder()
+                    .setToken(formattedToken)
+                    .setParentClientId(parentId)
+                    .build();
+
+            GetAllCredentialsResponse response = credentialStoreServiceClient.getCredentialByAgentBasicAuth(request);
+
+            return getAuthClaim(response);
+
+        } catch (Exception ex) {
+            throw new NotAuthorizedException("Wrong credentials " + ex.getMessage(), ex);
+        }
+
+    }
+
+
+    public String getToken(Metadata headers) {
+        String tokenWithBearer = headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER));
+        if (tokenWithBearer == null) {
+            tokenWithBearer = headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER));
+        }
+        if (tokenWithBearer == null) {
+            return null;
+        }
+        String prefix = "Bearer";
+        String token = tokenWithBearer.substring(prefix.length());
+        return token.trim();
+    }
+
+
+    /**
+     * Authorize tenant request by checking validity of calling tenant and its child tenant given by clientId
+     *
+     * @param headers       parentTenant Headers
+     * @param childClientId childTenant Headers
+     * @return AuthClaim of child tenant
+     */
+    public AuthClaim authorizeWithParentChildTenantValidationByBasicAuth(Metadata headers, String childClientId) {
+        AuthClaim authClaim = authorize(headers);
+
+        if (authClaim == null) {
+            return null;
+        }
+
+        if (childClientId == null || childClientId.trim().equals("")) {
+            return authClaim;
+        }
+
+        GetCredentialRequest request = GetCredentialRequest
+                .newBuilder()
+                .setId(childClientId).build();
+
+
+        CredentialMetadata metadata = credentialStoreServiceClient.getCustosCredentialFromClientId(request);
+
+
+        GetCredentialRequest credentialRequest = GetCredentialRequest
+                .newBuilder()
+                .setOwnerId(metadata.getOwnerId())
+                .setType(Type.IAM).build();
+
+        CredentialMetadata iamCredentials = credentialStoreServiceClient.getCredential(credentialRequest);
+
+        AuthClaim childClaim = getAuthClaim(metadata);
+
+        childClaim.setIamAuthSecret(iamCredentials.getSecret());
+        childClaim.setIamAuthId(iamCredentials.getId());
+
+        boolean statusValidation = validateTenantStatus(childClaim.getTenantId());
+
+        if (!statusValidation) {
+            return null;
+        }
+
+        boolean relationShipValidation = validateParentChildTenantRelationShip(authClaim.getTenantId(), childClaim.getTenantId());
+
+        if (!relationShipValidation) {
+            return null;
+        }
+
+        return childClaim;
+
+    }
+
+
+    public AuthClaim authorizeWithParentChildTenantValidationByBasicAuthAndUserTokenValidation(Metadata headers,
+                                                                                               String childClientId,
+                                                                                               String userToken) {
+        AuthClaim authClaim = authorize(headers);
+
+        if (authClaim == null) {
+            return null;
+        }
+
+        if (childClientId == null || childClientId.trim().equals("")) {
+            return authClaim;
+        }
+
+        GetCredentialRequest request = GetCredentialRequest
+                .newBuilder()
+                .setId(childClientId).build();
+
+        CredentialMetadata metadata = credentialStoreServiceClient.getCustosCredentialFromClientId(request);
+
+        AuthClaim childClaim = getAuthClaim(metadata);
+
+
+        boolean statusValidation = validateTenantStatus(childClaim.getTenantId());
+
+        if (!statusValidation) {
+            return null;
+        }
+
+        boolean relationShipValidation = validateParentChildTenantRelationShip(authClaim.getTenantId(), childClaim.getTenantId());
+
+        if (!relationShipValidation) {
+            return null;
+        }
+
+        return authorizeUsingUserToken(userToken);
+
+    }
+
+
+    public AuthToken getSAToken(String clientId, String clientSec, long tenantId) {
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setClientSecret(clientSec)
+                .setTenantId(tenantId)
+                .build();
+        return identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+    }
+
+
+    private AuthClaim getAuthClaim(GetAllCredentialsResponse response) {
+        if (response == null || response.getSecretListCount() == 0) {
+            return null;
+        }
+
+        AuthClaim authClaim = new AuthClaim();
+
+        authClaim.setPerformedBy(response.getRequesterUserEmail());
+        authClaim.setUsername(response.getRequesterUsername());
+        response.getSecretListList().forEach(metadata -> {
+
+                    if (metadata.getType() == Type.CUSTOS) {
+                        authClaim.setTenantId(metadata.getOwnerId());
+                        authClaim.setCustosId(metadata.getId());
+                        authClaim.setCustosSecret(metadata.getSecret());
+                        authClaim.setCustosIdIssuedAt(metadata.getClientIdIssuedAt());
+                        authClaim.setCustosSecretExpiredAt(metadata.getClientSecretExpiredAt());
+                        authClaim.setAdmin(metadata.getSuperAdmin());
+                        authClaim.setSuperTenant(metadata.getSuperTenant());
+                    } else if (metadata.getType() == Type.IAM) {
+                        authClaim.setIamAuthId(metadata.getId());
+                        authClaim.setIamAuthSecret(metadata.getSecret());
+
+                    } else if (metadata.getType() == Type.CILOGON) {
+                        authClaim.setCiLogonId(metadata.getId());
+                        authClaim.setCiLogonSecret(metadata.getSecret());
+                    } else if (metadata.getType() == Type.AGENT_CLIENT) {
+                        authClaim.setAgentClientId(metadata.getId());
+                        authClaim.setAgentClientSecret(metadata.getSecret());
+                    } else if (metadata.getType() == Type.AGENT) {
+                        authClaim.setAgentId(metadata.getId());
+                        authClaim.setAgentPassword(metadata.getInternalSec());
+                    }
+
+                }
+
+        );
+
+
+        GetTenantRequest tenantRequest = GetTenantRequest
+                .newBuilder()
+                .setTenantId(authClaim.getTenantId())
+                .build();
+
+        GetTenantResponse tentResp = tenantProfileClient.getTenant(tenantRequest);
+
+        if (tentResp.getTenant() != null && tentResp.getTenant().getTenantStatus().equals(TenantStatus.ACTIVE)) {
+            return authClaim;
+        }
+        return null;
+    }
+
+
+    private AuthClaim getAuthClaim(CredentialMetadata metadata) {
+        AuthClaim authClaim = new AuthClaim();
+        if (metadata.getType() == Type.CUSTOS) {
+            authClaim.setTenantId(metadata.getOwnerId());
+            authClaim.setCustosId(metadata.getId());
+            authClaim.setCustosSecret(metadata.getSecret());
+            authClaim.setCustosIdIssuedAt(metadata.getClientIdIssuedAt());
+            authClaim.setCustosSecretExpiredAt(metadata.getClientSecretExpiredAt());
+            authClaim.setAdmin(metadata.getSuperAdmin());
+            authClaim.setSuperTenant(metadata.getSuperTenant());
+        } else if (metadata.getType() == Type.IAM) {
+            authClaim.setIamAuthId(metadata.getId());
+            authClaim.setIamAuthSecret(metadata.getSecret());
+
+        } else if (metadata.getType() == Type.CILOGON) {
+            authClaim.setCiLogonId(metadata.getId());
+            authClaim.setCiLogonSecret(metadata.getSecret());
+        } else if (metadata.getType() == Type.AGENT_CLIENT) {
+            authClaim.setAgentClientId(metadata.getId());
+            authClaim.setAgentClientSecret(metadata.getSecret());
+        } else if (metadata.getType() == Type.AGENT) {
+            authClaim.setAgentId(metadata.getId());
+            authClaim.setAgentPassword(metadata.getInternalSec());
+        }
+        return authClaim;
+
+    }
+
+
+    private boolean validateTenantStatus(long tenantId) {
+        GetTenantRequest tenantRequest = GetTenantRequest
+                .newBuilder()
+                .setTenantId(tenantId)
+                .build();
+
+        GetTenantResponse tentResp = tenantProfileClient.getTenant(tenantRequest);
+
+        if (tentResp.getTenant() != null && tentResp.getTenant().getTenantStatus().equals(TenantStatus.ACTIVE)) {
+            return true;
+        }
+        return false;
+    }
+
+
+    private boolean validateParentChildTenantRelationShip(long parentId, long childTenantId) {
+
+        GetTenantRequest childTenantReq = GetTenantRequest
+                .newBuilder()
+                .setTenantId(childTenantId)
+                .build();
+
+        GetTenantResponse childTenantRes = tenantProfileClient.getTenant(childTenantReq);
+
+        Tenant childTenant = childTenantRes.getTenant();
+
+        // referring to same tenant
+        if (childTenant != null && childTenant.getTenantId() == parentId) {
+            return true;
+        }
+
+        //referring to child tenant
+        if (childTenant != null && childTenant.getTenantId() != parentId && childTenant.getParentTenantId() == parentId) {
+            return true;
+        }
+
+        return false;
+    }
+
+
+    private void attachTenantId(String tenantId, Metadata headers) {
+        headers.put(Metadata.Key.of(Constants.TenantId,Metadata.ASCII_STRING_MARSHALLER), tenantId);
+    }
+
+
+}
diff --git a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/LoggingInterceptor.java b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/LoggingInterceptor.java
new file mode 100644
index 0000000..9a5eb7a
--- /dev/null
+++ b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/LoggingInterceptor.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.services.commons.interceptors;
+
+import com.google.protobuf.Descriptors;
+import com.google.protobuf.GeneratedMessageV3;
+import io.grpc.Metadata;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.utils.Constants;
+import org.apache.custos.logging.client.LoggingClient;
+import org.apache.custos.logging.service.LogEvent;
+import org.apache.custos.logging.service.LoggingConfigurationRequest;
+import org.apache.custos.logging.service.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * API calling event capturing Interceptor
+ */
+@Component
+public class LoggingInterceptor implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingInterceptor.class);
+
+    private static final String X_FORWARDED_FOR = "x-forwarded-for";
+
+    @Autowired
+    private LoggingClient loggingClient;
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+
+
+        if (msg instanceof GeneratedMessageV3) {
+            Map<Descriptors.FieldDescriptor, Object> fieldDescriptors = ((GeneratedMessageV3) msg).getAllFields();
+
+            LogEvent.Builder logEventBuilder = LogEvent.newBuilder();
+            LoggingConfigurationRequest.Builder loggingConfigurationBuilder =
+                    LoggingConfigurationRequest.newBuilder();
+            boolean tenantMatched = false;
+            boolean clientMatched = false;
+
+            for (Descriptors.FieldDescriptor descriptor : fieldDescriptors.keySet()) {
+
+                if (descriptor.getName().equals("tenant_id") || descriptor.getName().equals("tenantId")) {
+                    logEventBuilder.setTenantId((long) fieldDescriptors.get(descriptor));
+                    loggingConfigurationBuilder.setTenantId((long) fieldDescriptors.get(descriptor));
+                    tenantMatched = true;
+                } else if (descriptor.getName().equals("client_id") || descriptor.getName().equals("clientId")) {
+                    logEventBuilder.setClientId((String) fieldDescriptors.get(descriptor));
+                    loggingConfigurationBuilder.setClientId((String) fieldDescriptors.get(descriptor));
+                    clientMatched = true;
+                } else if (descriptor.getName().equals("username") || descriptor.getName().equals("userId")) {
+                    logEventBuilder.setUsername((String) fieldDescriptors.get(descriptor));
+                }
+
+                String servicename = headers.
+                        get(Metadata.Key.of(Constants.SERVICE_NAME, Metadata.ASCII_STRING_MARSHALLER));
+                String externaIP = headers.
+                        get(Metadata.Key.of(Constants.X_FORWARDED_FOR, Metadata.ASCII_STRING_MARSHALLER));
+                logEventBuilder.setServiceName(servicename);
+                logEventBuilder.setEventType(method);
+                logEventBuilder.setExternalIp(externaIP);
+                logEventBuilder.setCreatedTime(System.currentTimeMillis());
+            }
+
+            if (tenantMatched && clientMatched) {
+                Status status = loggingClient.isLogEnabled(loggingConfigurationBuilder.build());
+                if (status.getStatus()) {
+                    loggingClient.addLogEventAsync(logEventBuilder.build());
+                }
+            }
+        }
+        return msg;
+    }
+}
diff --git a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/MultiTenantAuthInterceptor.java b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/MultiTenantAuthInterceptor.java
new file mode 100644
index 0000000..8b311e6
--- /dev/null
+++ b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/MultiTenantAuthInterceptor.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.services.commons.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.utils.Constants;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Responsible for authorization  of  multi tenant middleware requests
+ */
+public abstract class MultiTenantAuthInterceptor extends AuthInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AuthInterceptor.class);
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+    private TenantProfileClient tenantProfileClient;
+
+    private IdentityClient identityClient;
+
+    public MultiTenantAuthInterceptor(CredentialStoreServiceClient credentialStoreServiceClient,
+                                      TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+        this.tenantProfileClient = tenantProfileClient;
+        this.identityClient = identityClient;
+
+    }
+
+
+    public AuthClaim authorize(Metadata headers, String clientId) {
+
+        if (clientId != null && clientId.trim().equals("")) {
+            clientId = null;
+        }
+
+        String userToken = headers.get(Metadata.Key.of(Constants.USER_TOKEN, Metadata.ASCII_STRING_MARSHALLER));
+
+        if (clientId == null && userToken == null) {
+            return authorize(headers);
+        } else if (clientId != null && userToken == null) {
+            return authorizeWithParentChildTenantValidationByBasicAuth(headers, clientId);
+        } else if (clientId != null && userToken != null) {
+            return authorizeWithParentChildTenantValidationByBasicAuthAndUserTokenValidation(headers, clientId, userToken);
+        } else {
+            return authorizeUsingUserToken(headers);
+        }
+    }
+
+
+    public String getUserTokenFromUserTokenHeader(Metadata headers) {
+        return headers.get(Metadata.Key.of(Constants.USER_TOKEN, Metadata.ASCII_STRING_MARSHALLER));
+    }
+}
diff --git a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/model/AuthClaim.java b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/model/AuthClaim.java
new file mode 100644
index 0000000..16aedd5
--- /dev/null
+++ b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/model/AuthClaim.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.services.commons.model;
+
+public class AuthClaim {
+
+    private long tenantId;
+
+    private String iamAuthId;
+
+    private String iamAuthSecret;
+
+    private String ciLogonId;
+
+    private String ciLogonSecret;
+
+    private String custosId;
+
+    private String custosSecret;
+
+    private long custosIdIssuedAt;
+
+
+    private long custosSecretExpiredAt;
+
+    private String performedBy;
+
+    private boolean superTenant;
+
+    private boolean admin;
+
+    private String username;
+
+    private String agentClientId;
+
+    private String agentClientSecret;
+
+    private String agentPassword;
+
+    private String agentId;
+
+
+    public AuthClaim() {
+    }
+
+    public AuthClaim(long tenantId, String iamAuthId, String iamAuthSecret) {
+        this.tenantId = tenantId;
+        this.iamAuthId = iamAuthId;
+        this.iamAuthSecret = iamAuthSecret;
+    }
+
+    public long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(long tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getIamAuthId() {
+        return iamAuthId;
+    }
+
+    public void setIamAuthId(String iamAuthId) {
+        this.iamAuthId = iamAuthId;
+    }
+
+    public String getIamAuthSecret() {
+        return iamAuthSecret;
+    }
+
+    public void setIamAuthSecret(String iamAuthSecret) {
+        this.iamAuthSecret = iamAuthSecret;
+    }
+
+    public String getCiLogonId() {
+        return ciLogonId;
+    }
+
+    public void setCiLogonId(String ciLogonId) {
+        this.ciLogonId = ciLogonId;
+    }
+
+    public String getCiLogonSecret() {
+        return ciLogonSecret;
+    }
+
+    public void setCiLogonSecret(String ciLogonSecret) {
+        this.ciLogonSecret = ciLogonSecret;
+    }
+
+    public String getCustosId() {
+        return custosId;
+    }
+
+    public void setCustosId(String custosId) {
+        this.custosId = custosId;
+    }
+
+    public String getCustosSecret() {
+        return custosSecret;
+    }
+
+    public void setCustosSecret(String custosSecret) {
+        this.custosSecret = custosSecret;
+    }
+
+    public long getCustosIdIssuedAt() {
+        return custosIdIssuedAt;
+    }
+
+    public void setCustosIdIssuedAt(long custosIdIssuedAt) {
+        this.custosIdIssuedAt = custosIdIssuedAt;
+    }
+
+    public long getCustosSecretExpiredAt() {
+        return custosSecretExpiredAt;
+    }
+
+    public void setCustosSecretExpiredAt(long custosSecretExpiredAt) {
+        this.custosSecretExpiredAt = custosSecretExpiredAt;
+    }
+
+    public String getPerformedBy() {
+        return performedBy;
+    }
+
+    public void setPerformedBy(String performedBy) {
+        this.performedBy = performedBy;
+    }
+
+    public boolean isSuperTenant() {
+        return superTenant;
+    }
+
+    public void setSuperTenant(boolean superTenant) {
+        this.superTenant = superTenant;
+    }
+
+    public boolean isAdmin() {
+        return admin;
+    }
+
+    public void setAdmin(boolean admin) {
+        this.admin = admin;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+
+    public String getAgentClientId() {
+        return agentClientId;
+    }
+
+    public void setAgentClientId(String agentClientId) {
+        this.agentClientId = agentClientId;
+    }
+
+    public String getAgentClientSecret() {
+        return agentClientSecret;
+    }
+
+    public void setAgentClientSecret(String agentClientSecret) {
+        this.agentClientSecret = agentClientSecret;
+    }
+
+    public String getAgentPassword() {
+        return agentPassword;
+    }
+
+    public void setAgentPassword(String agentPassword) {
+        this.agentPassword = agentPassword;
+    }
+
+    public String getAgentId() {
+        return agentId;
+    }
+
+    public void setAgentId(String agentId) {
+        this.agentId = agentId;
+    }
+}
diff --git a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/utils/InterServiceModelMapper.java b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/utils/InterServiceModelMapper.java
new file mode 100644
index 0000000..9bfeb01
--- /dev/null
+++ b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/utils/InterServiceModelMapper.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.integration.services.commons.utils;
+
+import org.apache.custos.iam.service.UserAttribute;
+import org.apache.custos.iam.service.UserRepresentation;
+import org.apache.custos.user.profile.service.UserProfile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class InterServiceModelMapper {
+
+
+    public static UserProfile convert(UserRepresentation representation) {
+        UserProfile.Builder profileBuilder = UserProfile.newBuilder();
+
+        if (representation.getRealmRolesCount() > 0) {
+            profileBuilder.addAllRealmRoles(representation.getRealmRolesList());
+        }
+
+        if (representation.getClientRolesCount() > 0) {
+            profileBuilder.addAllClientRoles(representation.getClientRolesList());
+        }
+
+        if (representation.getAttributesCount() > 0) {
+            List<UserAttribute> attributeList = representation.getAttributesList();
+            List<org.apache.custos.user.profile.service.UserAttribute> userAtrList = new ArrayList<>();
+            attributeList.forEach(atr -> {
+                org.apache.custos.user.profile.service.UserAttribute userAttribute =
+                        org.apache.custos.user.profile.service.UserAttribute
+                                .newBuilder()
+                                .setKey(atr.getKey())
+                                .addAllValue(atr.getValuesList())
+                                .build();
+
+                userAtrList.add(userAttribute);
+            });
+            profileBuilder.addAllAttributes(userAtrList);
+        }
+
+        profileBuilder.setUsername(representation.getUsername().toLowerCase());
+        profileBuilder.setFirstName(representation.getFirstName());
+        profileBuilder.setLastName(representation.getLastName());
+        profileBuilder.setEmail(representation.getEmail());
+
+        return profileBuilder.build();
+    }
+
+
+}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service-sidecar/Dockerfile b/custos-integration-services/group-management-service-parent/group-management-service-sidecar/Dockerfile
new file mode 100644
index 0000000..7172f41
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service-sidecar/Dockerfile
@@ -0,0 +1,3 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/group-management-service.pb /data/group-management-service.pb
+COPY src/main/resources/envoy.yaml  /etc/envoy/envoy.yaml
diff --git a/custos-integration-services/group-management-service-parent/group-management-service-sidecar/pom.xml b/custos-integration-services/group-management-service-parent/group-management-service-sidecar/pom.xml
new file mode 100644
index 0000000..324bfe2
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service-sidecar/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>group-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>group-management-service-sidecar</artifactId>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/group-management-service-parent/group-management-service-sidecar/src/main/resources/envoy.yaml b/custos-integration-services/group-management-service-parent/group-management-service-sidecar/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..46eff51
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service-sidecar/src/main/resources/envoy.yaml
@@ -0,0 +1,48 @@
+admin:
+  access_log_path: /tmp/admin_access.log
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+  listeners:
+    - name: main-listener
+      address:
+        socket_address: { address: 0.0.0.0, port_value: 50000 }
+      filter_chains:
+        - filters:
+            - name: envoy.http_connection_manager
+              config:
+                stat_prefix: grpc_json
+                codec_type: AUTO
+                route_config:
+                  name: local_route
+                  virtual_hosts:
+                    - name: local_service
+                      domains: ["*"]
+                      routes:
+                        - match: { prefix: "/", grpc: {} }
+                          route: { cluster: grpc-backend-services, timeout: { seconds: 60 } }
+                http_filters:
+                  - name: envoy.grpc_json_transcoder
+                    config:
+                      proto_descriptor: "/data/group-management-service.pb"
+                      services: ["org.apache.custos.group.management.service.GroupManagementService"]
+                      convert_grpc_status: true
+                      print_options:
+                        add_whitespace: true
+                        always_print_primitive_fields: true
+                        always_print_enums_as_ints: false
+                        preserve_proto_field_names: true
+                  - name: envoy.router
+
+  clusters:
+    - name: grpc-backend-services
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: localhost
+            port_value: 7000
diff --git a/custos-integration-services/group-management-service-parent/group-management-service-sidecar/src/main/resources/group-management-service.pb b/custos-integration-services/group-management-service-parent/group-management-service-sidecar/src/main/resources/group-management-service.pb
new file mode 100644
index 0000000..11c7db6
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service-sidecar/src/main/resources/group-management-service.pb
Binary files differ
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/Dockerfile b/custos-integration-services/group-management-service-parent/group-management-service/Dockerfile
new file mode 100644
index 0000000..6457ff8
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/pom.xml b/custos-integration-services/group-management-service-parent/group-management-service/pom.xml
new file mode 100644
index 0000000..1ac8b6f
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/pom.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>group-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>group-management-service</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>iam-admin-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.api.grpc</groupId>
+            <artifactId>proto-google-common-protos</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/.helmignore b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/Chart.yaml b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..f5043f8
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos group management service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/NOTES.txt b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/_helpers.tpl b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/deployment.yaml b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..a0957f6
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,78 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+            - name: grpc
+              containerPort: {{ .Values.service.grpcport }}
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: {{ .Values.service.port }}
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+        - name: {{ .Chart.Name }}-envoy-proxy
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.proxy.repository }}:{{ .Values.proxy.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: envoyhttp
+              containerPort: {{ .Values.proxy.port }}
+              protocol: TCP
+            - name: adminhttp
+              containerPort: {{ .Values.proxy.adminport }}
+              protocol: TCP
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/ingress-grpc.yaml b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/ingress-grpc.yaml
new file mode 100644
index 0000000..727abc1
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/ingress-grpc.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: "nginx"
+    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
+    cert-manager.io/cluster-issuer: letsencrypt-production
+  name: ${artifactId}-ingress-grpc
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /org.apache.custos.group.management.service.GroupManagementService(/|$)(.*)
+            backend:
+              serviceName: group-management-service
+              servicePort: grpc
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/ingress.yaml b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..70f3029
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
+kind: Ingress
+metadata:
+  name: ${artifactId}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /group-management/$2
+    cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /group-management(/|$)(.*)
+            backend:
+              serviceName: group-management-service
+              servicePort: envoyhttp
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/service.yaml b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..878d1fb
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,24 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.grpcport }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+    - port: {{ .Values.proxy.port }}
+      targetPort: envoyhttp
+      protocol: TCP
+      name: envoyhttp
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/serviceaccount.yaml b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/tests/test-connection.yaml b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/values.yaml b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..fc25587
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/helm/values.yaml
@@ -0,0 +1,84 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+proxy:
+   repository: apachecustos/group-management-service-sidecar
+   tag: 1.0-SNAPSHOT
+   port: 50000
+   adminport: 9901
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/GroupManagementServiceInitializer.java b/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/GroupManagementServiceInitializer.java
new file mode 100644
index 0000000..4120359
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/GroupManagementServiceInitializer.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.group.management;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ClientInterceptor;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.group.management.interceptors.ClientAuthInterceptorImpl;
+import org.apache.custos.group.management.interceptors.InputValidator;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
+import org.apache.custos.integration.services.commons.interceptors.LoggingInterceptor;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+import java.util.Stack;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "org.apache.custos")
+public class GroupManagementServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(GroupManagementServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        //   Tracing tracing1 =  Tracing.newBuilder().build();
+        return GrpcTracing.create(tracing);
+    }
+
+    //We also create a client-side interceptor and put that in the context, this interceptor can then be injected into gRPC clients and
+    //then applied to the managed channel.
+    @Bean
+    ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newClientInterceptor();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public Stack<IntegrationServiceInterceptor> getInterceptorSet(InputValidator inputValidator,
+                                                                  ClientAuthInterceptorImpl authInterceptor,
+                                                                  LoggingInterceptor loggingInterceptor) {
+        Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
+        interceptors.add(inputValidator);
+        interceptors.add(authInterceptor);
+        interceptors.add(loggingInterceptor);
+        return interceptors;
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(Stack<IntegrationServiceInterceptor> integrationServiceInterceptors) {
+        return new ServiceInterceptor(integrationServiceInterceptors);
+    }
+}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/interceptors/ClientAuthInterceptorImpl.java b/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/interceptors/ClientAuthInterceptorImpl.java
new file mode 100644
index 0000000..fc4aa95
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/interceptors/ClientAuthInterceptorImpl.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.group.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.iam.service.GroupRequest;
+import org.apache.custos.iam.service.GroupsRequest;
+import org.apache.custos.iam.service.UserGroupMappingRequest;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.core.utils.Constants;
+import org.apache.custos.integration.services.commons.interceptors.MultiTenantAuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.user.profile.service.GroupMembership;
+import org.apache.custos.user.profile.service.GroupToGroupMembership;
+import org.apache.custos.user.profile.service.UserProfileRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate confidential client specific authorization.
+ * Methods which authenticates based only on client are implemented here.
+ */
+@Component
+public class ClientAuthInterceptorImpl extends MultiTenantAuthInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+    @Autowired
+    public ClientAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT reqT) {
+
+
+        if (method.equals("findGroup") || method.equals("getAllGroups")
+                || method.equals("updateGroup") || method.equals("deleteGroup")) {
+            GroupRequest request = (GroupRequest) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+
+            AuthToken token = getSAToken(claim.getIamAuthId(), claim.getIamAuthSecret(), claim.getTenantId());
+            if (token == null || token.getAccessToken() == null) {
+                throw new NotAuthorizedException("Request is not authorized SA token is invalid", null);
+            }
+
+
+            return (ReqT) ((GroupRequest) reqT).toBuilder()
+                    .setClientId(oauthId)
+                    .setTenantId(tenantId)
+                    .setClientSec(oauthSec)
+                    .setAccessToken(token.getAccessToken())
+                    .setPerformedBy(claim.getPerformedBy() != null ? claim.getPerformedBy(): Constants.SYSTEM)
+                    .build();
+
+        } else if (method.equals("createGroups")) {
+            GroupsRequest request = (GroupsRequest) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+
+            AuthToken token = getSAToken(claim.getIamAuthId(), claim.getIamAuthSecret(), claim.getTenantId());
+            if (token == null || token.getAccessToken() == null) {
+                throw new NotAuthorizedException("Request is not authorized SA token is invalid", null);
+            }
+
+
+            return (ReqT) ((GroupsRequest) reqT).toBuilder()
+                    .setClientId(oauthId)
+                    .setTenantId(tenantId)
+                    .setClientSec(oauthSec)
+                    .setAccessToken(token.getAccessToken())
+                    .setPerformedBy(claim.getPerformedBy() != null ? claim.getPerformedBy(): Constants.SYSTEM)
+                    .build();
+
+        } else if (method.equals("addUserToGroup") || method.equals("removeUserFromGroup")) {
+            UserGroupMappingRequest request = (UserGroupMappingRequest) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            AuthToken token = getSAToken(claim.getIamAuthId(), claim.getIamAuthSecret(), claim.getTenantId());
+            if (token == null || token.getAccessToken() == null) {
+                throw new NotAuthorizedException("Request is not authorized SA token is invalid", null);
+            }
+
+
+            return (ReqT) ((UserGroupMappingRequest) reqT).toBuilder()
+                    .setClientId(oauthId)
+                    .setClientSec(oauthSec)
+                    .setTenantId(tenantId)
+                    .setAccessToken(token.getAccessToken())
+                    .setPerformedBy(claim.getPerformedBy() != null ? claim.getPerformedBy(): Constants.SYSTEM)
+                    .build();
+
+        } else if (method.equals("addChildGroupToParentGroup") || method.equals("removeChildGroupFromParentGroup")) {
+            GroupToGroupMembership groupToGroupMembership = (GroupToGroupMembership)reqT;
+            AuthClaim claim = authorize(headers, groupToGroupMembership.getClientId());
+
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            long tenantId = claim.getTenantId();
+
+
+            return (ReqT) ((GroupToGroupMembership) reqT).toBuilder()
+                    .setTenantId(tenantId)
+                    .build();
+
+
+        } else if (method.equals("getAllGroupsOfUser")) {
+            UserProfileRequest request = (UserProfileRequest)reqT;
+            AuthClaim claim = authorize(headers,request.getClientId());
+
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            long tenantId = claim.getTenantId();
+
+            return (ReqT) ((UserProfileRequest) reqT).toBuilder()
+                    .setTenantId(tenantId)
+                    .build();
+
+
+        } else if (method.equals("getAllChildUsers") || method.equals("getAllChildGroups")
+                || method.equals("getAllParentGroupsOfGroup")) {
+
+            org.apache.custos.user.profile.service.GroupRequest request =
+                    (org.apache.custos.user.profile.service.GroupRequest) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            long tenantId = claim.getTenantId();
+
+
+            return (ReqT) ((org.apache.custos.user.profile.service.GroupRequest) reqT).toBuilder()
+                    .setTenantId(tenantId)
+                    .build();
+        } else if (method.equals("changeUserMembershipType") || method.equals("hasAccess")) {
+            GroupMembership request =
+                    (GroupMembership) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            long tenantId = claim.getTenantId();
+
+            return (ReqT) ((GroupMembership) reqT).toBuilder()
+                    .setTenantId(tenantId)
+                    .build();
+        }
+        return reqT;
+    }
+
+
+}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/interceptors/InputValidator.java b/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/interceptors/InputValidator.java
new file mode 100644
index 0000000..ce6cdc1
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/interceptors/InputValidator.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.group.management.interceptors;
+
+
+import io.grpc.Metadata;
+import org.apache.custos.integration.core.exceptions.MissingParameterException;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class validates the  request input parameters
+ */
+@Component
+public class InputValidator implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param body
+     * @return
+     */
+    private void validate(String methodName, Object body, Metadata headers) {
+
+        switch (methodName) {
+            case "createGroups":
+            case "updateGroup":
+            case "deleteGroup":
+            case "findGroup":
+            case "getAllGroups":
+            case "addUserToGroup":
+            case "removeUserFromGroup":
+            case "addChildGroupToParentGroup":
+            case "removeChildGroupFromParentGroup":
+            case "getAllGroupsOfUser":
+            case "getAllParentGroupsOfGroup":
+                validateMethods(methodName, body, headers);
+                break;
+            default:
+        }
+    }
+
+
+    private boolean validateMethods(String methodName, Object body, Metadata headers) {
+        validationAuthorizationHeader(headers);
+        return true;
+    }
+
+
+    private boolean validationAuthorizationHeader(Metadata headers) {
+        if (headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER)) == null
+                || headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)) == null) {
+            throw new MissingParameterException("authorization header not available", null);
+        }
+
+        return true;
+    }
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        validate(method, msg, headers);
+        return msg;
+    }
+}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/service/GroupManagementService.java b/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/service/GroupManagementService.java
new file mode 100644
index 0000000..296a8b6
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/java/org/apache/custos/group/management/service/GroupManagementService.java
@@ -0,0 +1,614 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.group.management.service;
+
+
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.iam.admin.client.IamAdminServiceClient;
+import org.apache.custos.iam.service.GroupRequest;
+import org.apache.custos.iam.service.UserAttribute;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.identity.service.GetUserManagementSATokenRequest;
+import org.apache.custos.user.profile.client.UserProfileClient;
+import org.apache.custos.user.profile.service.*;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@GRpcService
+public class GroupManagementService extends GroupManagementServiceGrpc.GroupManagementServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(GroupManagementService.class);
+
+    @Autowired
+    private UserProfileClient userProfileClient;
+
+    @Autowired
+    private IamAdminServiceClient iamAdminServiceClient;
+
+
+    @Autowired
+    private IdentityClient identityClient;
+
+
+    //TODO: improve error handling to avoid database consistency
+    @Override
+    public void createGroups(GroupsRequest request, StreamObserver<GroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received create Groups for tenant " + request.getTenantId());
+
+            GroupsResponse response = iamAdminServiceClient.createGroups(request);
+
+
+            List<org.apache.custos.user.profile.service.GroupRequest> groupRequests =
+                    getAllGroupRequests(response.getGroupsList(), null, request.getTenantId(), request.getPerformedBy());
+
+
+            for (org.apache.custos.user.profile.service.GroupRequest groupRequest : groupRequests) {
+
+                userProfileClient.createGroup(groupRequest);
+            }
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at createGroups " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    //TODO: improve error handling to avoid database consistency
+    @Override
+    public void updateGroup(GroupRequest request, StreamObserver<GroupRepresentation> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateGroup for tenant " + request.getTenantId());
+
+            GroupRepresentation gr = request.getGroup();
+
+            if (request.getId() != null && ! request.getId().trim().equals("")) {
+                gr = gr.toBuilder().setId(request.getId()).build();
+            }
+            request = request.toBuilder().setGroup(gr).build();
+
+            GroupRepresentation response = iamAdminServiceClient.updateGroup(request);
+
+            List<GroupRepresentation> representations = new ArrayList<>();
+            representations.add(response);
+
+            Group group = Group.newBuilder()
+                    .setName(response.getName())
+                    .setId(response.getId())
+                    .build();
+
+            org.apache.custos.user.profile.service.GroupRequest groupRequest = org.apache.custos.user.profile.service.GroupRequest
+                    .newBuilder().
+                            setTenantId(request.getTenantId()).
+                            setPerformedBy(request.getPerformedBy()).
+                            setGroup(group).build();
+
+            Group exGroup = userProfileClient.getGroup(groupRequest);
+
+
+            List<org.apache.custos.user.profile.service.GroupRequest> groupRequests =
+                    getAllGroupRequests(representations, exGroup.getParentId(), request.getTenantId(), request.getPerformedBy());
+
+
+            userProfileClient.updateGroup(groupRequests.get(0));
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred at updateGroup " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    //TODO: improve error handling to avoid database consistency
+    @Override
+    public void deleteGroup(GroupRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateGroup for tenant " + request.getTenantId());
+
+            GroupRepresentation gr = request.getGroup();
+            if (request.getId() != null && ! request.getId().trim().equals("")) {
+                gr = gr.toBuilder().setId(request.getId()).build();
+            }
+            request = request.toBuilder().setGroup(gr).build();
+
+            OperationStatus response = iamAdminServiceClient.deleteGroup(request);
+
+            Group group = Group.newBuilder()
+                    .setId(request.getGroup().getId())
+                    .build();
+
+            org.apache.custos.user.profile.service.GroupRequest groupRequest = org.apache.custos.user.profile.service.GroupRequest
+                    .newBuilder().
+                            setTenantId(request.getTenantId()).
+                            setPerformedBy(request.getPerformedBy()).
+                            setGroup(group).build();
+
+            userProfileClient.deleteGroup(groupRequest);
+
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at deleteGroup " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void findGroup(GroupRequest request, StreamObserver<GroupRepresentation> responseObserver) {
+        try {
+            LOGGER.debug("Request received findGroup for group Id " + request.getGroup().getId() + " of  tenant "
+                    + request.getTenantId());
+
+
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+
+                request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+
+                GroupRepresentation representation = iamAdminServiceClient.findGroup(request);
+
+                responseObserver.onNext(representation);
+                responseObserver.onCompleted();
+            } else {
+                String msg = "Error occurred at findGroup, authentication token not found ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at findGroup " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void getAllGroups(GroupRequest request, StreamObserver<GroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received getAllGroups for  tenant "
+                    + request.getTenantId());
+
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+
+                request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+
+                GroupsResponse response = iamAdminServiceClient.getAllGroups(request);
+
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            } else {
+                String msg = "Error occurred at findGroup, authentication token not found ";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAllGroups " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void addUserToGroup(UserGroupMappingRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addUserToGroup for  user  " + request.getUsername() + " of tenant "
+                    + request.getTenantId());
+
+            OperationStatus status = iamAdminServiceClient.addUserToGroup(request);
+
+
+            if (status.getStatus()) {
+
+                GroupMembership membership = GroupMembership
+                        .newBuilder()
+                        .setGroupId(request.getGroupId())
+                        .setUsername(request.getUsername())
+                        .setTenantId(request.getTenantId())
+                        .setType(request.getMembershipType())
+                        .build();
+
+                userProfileClient.addUserToGroup(membership);
+
+
+            }
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at addUserToGroup " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void removeUserFromGroup(UserGroupMappingRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to removeUserFromGroup for  user  " + request.getUsername() + " of tenant "
+                    + request.getTenantId());
+
+
+            OperationStatus status = iamAdminServiceClient.removeUserFromGroup(request);
+
+
+            if (status.getStatus()) {
+
+                GroupMembership membership = GroupMembership
+                        .newBuilder()
+                        .setGroupId(request.getGroupId())
+                        .setUsername(request.getUsername())
+                        .setTenantId(request.getTenantId())
+                        .build();
+
+                userProfileClient.removeUserFromGroup(membership);
+
+            }
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at removeUserFromGroup " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void addChildGroupToParentGroup(GroupToGroupMembership request,
+                                           StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to addChildGroupToParentGroup for  group  " + request.getChildId() +
+                    " to add " + request.getParentId() + " of tenant " + request.getTenantId());
+
+            org.apache.custos.user.profile.service.Status status = userProfileClient.addChildGroupToParentGroup(request);
+
+            OperationStatus operationStatus = OperationStatus.newBuilder().setStatus(status.getStatus()).build();
+
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at addChildGroupToParentGroup " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void removeChildGroupFromParentGroup(GroupToGroupMembership request,
+                                                StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to removeUserFromGroup for  group  " + request.getChildId() +
+                    " to remove " + request.getParentId() + " of tenant " + request.getTenantId());
+
+            org.apache.custos.user.profile.service.Status status = userProfileClient.removeChildGroupFromParentGroup(request);
+
+            OperationStatus operationStatus = OperationStatus.newBuilder().setStatus(status.getStatus()).build();
+
+            responseObserver.onNext(operationStatus);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at removeChildGroupFromParentGroup " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void getAllGroupsOfUser(UserProfileRequest request,
+                                   StreamObserver<GetAllGroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllGroupsOfUser for  user  " + request.getProfile().getUsername() + " of tenant "
+                    + request.getTenantId());
+
+            GetAllGroupsResponse response = userProfileClient.getAllGroupsOfUser(request);
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAllGroupsOfUser " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void getAllParentGroupsOfGroup(org.apache.custos.user.profile.service.GroupRequest request,
+                                          StreamObserver<GetAllGroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllParentGroupsOfGroup for  group  "
+                    + request.getGroup().getId() + " of tenant " + request.getTenantId());
+
+            GetAllGroupsResponse response = userProfileClient.getAllParentGroupsOfGroup(request);
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAllParentGroupsOfGroup " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void getAllChildUsers(org.apache.custos.user.profile.service.GroupRequest request, StreamObserver<GetAllUserProfilesResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllChildUsers for  group  "
+                    + request.getGroup().getId() + " of tenant " + request.getTenantId());
+
+            GetAllUserProfilesResponse response = userProfileClient.getAllChildUsers(request);
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAllChildUsers " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void getAllChildGroups(org.apache.custos.user.profile.service.GroupRequest request, StreamObserver<GetAllGroupsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllChildGroups for  group  "
+                    + request.getGroup().getId() + " of tenant " + request.getTenantId());
+
+            GetAllGroupsResponse response = userProfileClient.getAllChildGroups(request);
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAllChildGroups " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void changeUserMembershipType(GroupMembership request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to changeUserMembershipType for  user  "
+                    + request.getUsername() + " of tenant " + request.getTenantId());
+
+            org.apache.custos.user.profile.service.Status response = userProfileClient.changeUserMembershipType(request);
+
+            OperationStatus status = OperationStatus.newBuilder().setStatus(response.getStatus()).build();
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at changeUserMembershipType " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void hasAccess(GroupMembership request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to hasAccess for  user  "
+                    + request.getUsername() + " of tenant " + request.getTenantId());
+
+            org.apache.custos.user.profile.service.Status response = userProfileClient.hasAccess(request);
+
+            OperationStatus status = OperationStatus.newBuilder().setStatus(response.getStatus()).build();
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at hasAccess " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    private org.apache.custos.user.profile.service.GroupRequest createGroup(GroupRepresentation representation,
+                                                                            String parentId,
+                                                                            long tenantId,
+                                                                            String performedBy) {
+
+        List<GroupAttribute> attributes = new ArrayList<>();
+
+        if (representation.getAttributesList() != null && !representation.getAttributesList().isEmpty()) {
+            for (UserAttribute attribute : representation.getAttributesList()) {
+                GroupAttribute groupAttribute = GroupAttribute
+                        .newBuilder()
+                        .setKey(attribute.getKey())
+                        .addAllValue(attribute.getValuesList()).build();
+                attributes.add(groupAttribute);
+
+            }
+
+
+        }
+
+        Group group = Group
+                .newBuilder()
+                .setId(representation.getId())
+                .setName(representation.getName())
+                .addAllClientRoles(representation.getClientRolesList())
+                .addAllRealmRoles(representation.getRealmRolesList())
+                .addAllAttributes(attributes)
+                .build();
+
+        if (parentId != null) {
+            group = group.toBuilder().setParentId(parentId).build();
+        }
+
+        if (representation.getOwnerId() != null && !representation.getOwnerId().trim().equals("")) {
+            group = group.toBuilder().setOwnerId(representation.getOwnerId()).build();
+        }
+
+        if (representation.getDescription() != null && !representation.getDescription().trim().equals("")) {
+            group = group.toBuilder().setDescription(representation.getDescription()).build();
+        }
+
+        org.apache.custos.user.profile.service.GroupRequest groupRequest =
+
+                org.apache.custos.user.profile.service.GroupRequest
+                        .newBuilder()
+                        .setTenantId(tenantId)
+                        .setPerformedBy(performedBy)
+                        .setGroup(group).build();
+
+        return groupRequest;
+
+
+    }
+
+
+    private List<org.apache.custos.user.profile.service.GroupRequest> getAllGroupRequests
+            (List<GroupRepresentation> groupRepresentations, String parentId, long tenantId, String performedBy) {
+
+        List<org.apache.custos.user.profile.service.GroupRequest> groupRequests = new ArrayList<>();
+        for (GroupRepresentation representation : groupRepresentations) {
+
+            org.apache.custos.user.profile.service.GroupRequest groupRequest =
+                    createGroup(representation, parentId, tenantId, performedBy);
+            groupRequests.add(groupRequest);
+
+            if (representation.getSubGroupsList() != null && !representation.getSubGroupsList().isEmpty()) {
+
+                List<org.apache.custos.user.profile.service.GroupRequest> list =
+                        getAllGroupRequests(representation.getSubGroupsList(), representation.getId(), tenantId, performedBy);
+
+                if (!list.isEmpty()) {
+                    groupRequests.addAll(list);
+                }
+
+            }
+
+        }
+
+        return groupRequests;
+
+    }
+
+
+}
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/proto/GroupManagementService.proto b/custos-integration-services/group-management-service-parent/group-management-service/src/main/proto/GroupManagementService.proto
new file mode 100644
index 0000000..faab105
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/proto/GroupManagementService.proto
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.group.management.service;
+
+import "google/api/annotations.proto";
+import "UserProfileService.proto";
+import "IamAdminService.proto";
+
+
+service GroupManagementService {
+
+    rpc createGroups (org.apache.custos.iam.service.GroupsRequest) returns (org.apache.custos.iam.service.GroupsResponse) {
+
+        option (google.api.http) = {
+           post: "/group-management/v1.0.0/groups"
+         };
+    }
+
+
+    rpc updateGroup (org.apache.custos.iam.service.GroupRequest) returns (org.apache.custos.iam.service.GroupRepresentation) {
+
+        option (google.api.http) = {
+           put: "/group-management/v1.0.0/group/{id}"
+         };
+    }
+
+    rpc deleteGroup (org.apache.custos.iam.service.GroupRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+
+        option (google.api.http) = {
+           delete: "/group-management/v1.0.0/group/{id}"
+         };
+    }
+
+    rpc findGroup (org.apache.custos.iam.service.GroupRequest) returns (org.apache.custos.iam.service.GroupRepresentation) {
+
+        option (google.api.http) = {
+           get: "/group-management/v1.0.0/group"
+         };
+    }
+
+
+    rpc getAllGroups (org.apache.custos.iam.service.GroupRequest) returns (org.apache.custos.iam.service.GroupsResponse) {
+
+        option (google.api.http) = {
+           get: "/group-management/v1.0.0/groups"
+         };
+    }
+
+    rpc addUserToGroup (org.apache.custos.iam.service.UserGroupMappingRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+
+        option (google.api.http) = {
+           post: "/group-management/v1.0.0/user/group/membership"
+         };
+    }
+
+
+    rpc removeUserFromGroup (org.apache.custos.iam.service.UserGroupMappingRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+
+        option (google.api.http) = {
+           delete: "/group-management/v1.0.0/user/group/membership"
+         };
+    }
+
+    rpc addChildGroupToParentGroup (org.apache.custos.user.profile.service.GroupToGroupMembership) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/group-management/v1.0.0/group/membership"
+         };
+
+    }
+    rpc removeChildGroupFromParentGroup (org.apache.custos.user.profile.service.GroupToGroupMembership) returns (org.apache.custos.iam.service.OperationStatus) {
+
+        option (google.api.http) = {
+           delete: "/group-management/v1.0.0/group/membership"
+         };
+    }
+
+    rpc getAllGroupsOfUser (org.apache.custos.user.profile.service.UserProfileRequest) returns (org.apache.custos.user.profile.service.GetAllGroupsResponse) {
+
+        option (google.api.http) = {
+           get: "/group-management/v1.0.0/user/group/memberships"
+         };
+    }
+
+    rpc getAllParentGroupsOfGroup (org.apache.custos.user.profile.service.GroupRequest) returns (org.apache.custos.user.profile.service.GetAllGroupsResponse) {
+        option (google.api.http) = {
+           get: "/group-management/v1.0.0/groups/memberships"
+         };
+
+    }
+
+
+    rpc getAllChildUsers(org.apache.custos.user.profile.service.GroupRequest) returns (org.apache.custos.user.profile.service.GetAllUserProfilesResponse) {
+        option (google.api.http) = {
+           get: "/group-management/v1.0.0/user/group/memberships/child"
+         };
+
+    }
+    rpc getAllChildGroups(org.apache.custos.user.profile.service.GroupRequest) returns (org.apache.custos.user.profile.service.GetAllGroupsResponse) {
+        option (google.api.http) = {
+           get: "/group-management/v1.0.0/groups/memberships/child"
+         };
+
+    }
+    rpc changeUserMembershipType (org.apache.custos.user.profile.service.GroupMembership) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           put: "/group-management/v1.0.0/user/group/membership"
+         };
+
+    }
+    rpc hasAccess(org.apache.custos.user.profile.service.GroupMembership) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           get: "/group-management/v1.0.0/user/group/access"
+         };
+
+    }
+
+
+}
+
+
+
+
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/resources/application.properties b/custos-integration-services/group-management-service-parent/group-management-service/src/main/resources/application.properties
new file mode 100644
index 0000000..3af6681
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/resources/application.properties
@@ -0,0 +1,28 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+server.port=8080
+grpc.port=7000
+spring.application.name=groupManagementService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
diff --git a/custos-integration-services/group-management-service-parent/group-management-service/src/main/resources/bootstrap.properties b/custos-integration-services/group-management-service-parent/group-management-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/group-management-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default
diff --git a/custos-integration-services/group-management-service-parent/pom.xml b/custos-integration-services/group-management-service-parent/pom.xml
new file mode 100644
index 0000000..c0151ce
--- /dev/null
+++ b/custos-integration-services/group-management-service-parent/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>group-management-service-parent</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>group-management-service</module>
+        <module>group-management-service-sidecar</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/Dockerfile b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/Dockerfile
new file mode 100644
index 0000000..4313e0f
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/Dockerfile
@@ -0,0 +1,3 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/identity-management-service.pb /data/identity-management-service.pb
+COPY src/main/resources/envoy.yaml  /etc/envoy/envoy.yaml
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/pom.xml b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/pom.xml
new file mode 100644
index 0000000..1347257
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>identity-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>identity-management-service-sidecar</artifactId>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/envoy.yaml b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..f7b0f88
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/envoy.yaml
@@ -0,0 +1,48 @@
+admin:
+  access_log_path: /tmp/admin_access.log
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+  listeners:
+    - name: main-listener
+      address:
+        socket_address: { address: 0.0.0.0, port_value: 50000 }
+      filter_chains:
+        - filters:
+            - name: envoy.http_connection_manager
+              config:
+                stat_prefix: grpc_json
+                codec_type: AUTO
+                route_config:
+                  name: local_route
+                  virtual_hosts:
+                    - name: local_service
+                      domains: ["*"]
+                      routes:
+                        - match: { prefix: "/", grpc: {} }
+                          route: { cluster: grpc-backend-services, timeout: { seconds: 60 } }
+                http_filters:
+                  - name: envoy.grpc_json_transcoder
+                    config:
+                      proto_descriptor: "/data/identity-management-service.pb"
+                      services: ["org.apache.custos.identity.management.service.IdentityManagementService"]
+                      convert_grpc_status: true
+                      print_options:
+                        add_whitespace: false
+                        always_print_primitive_fields: true
+                        always_print_enums_as_ints: false
+                        preserve_proto_field_names: true
+                  - name: envoy.router
+
+  clusters:
+    - name: grpc-backend-services
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: localhost
+            port_value: 7000
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/identity-management-service.pb b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/identity-management-service.pb
new file mode 100644
index 0000000..7d6ebaa
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service-sidecar/src/main/resources/identity-management-service.pb
Binary files differ
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/Dockerfile b/custos-integration-services/identity-management-service-parent/identity-management-service/Dockerfile
new file mode 100644
index 0000000..6457ff8
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/pom.xml b/custos-integration-services/identity-management-service-parent/identity-management-service/pom.xml
new file mode 100644
index 0000000..7ced6c4
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/pom.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>identity-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>identity-management-service</artifactId>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.api.grpc</groupId>
+            <artifactId>proto-google-common-protos</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/.helmignore b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/Chart.yaml b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..fe2b92b
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos identity management service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/NOTES.txt b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/_helpers.tpl b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/deployment.yaml b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..a0957f6
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,78 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+            - name: grpc
+              containerPort: {{ .Values.service.grpcport }}
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: {{ .Values.service.port }}
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+        - name: {{ .Chart.Name }}-envoy-proxy
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.proxy.repository }}:{{ .Values.proxy.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: envoyhttp
+              containerPort: {{ .Values.proxy.port }}
+              protocol: TCP
+            - name: adminhttp
+              containerPort: {{ .Values.proxy.adminport }}
+              protocol: TCP
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/ingress-grpc.yaml b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/ingress-grpc.yaml
new file mode 100644
index 0000000..0fbbed6
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/ingress-grpc.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: "nginx"
+    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
+    cert-manager.io/cluster-issuer: letsencrypt-production
+  name: ${artifactId}-ingress-grpc
+spec:
+  rules:
+     - host: custos.scigap.org
+       http:
+        paths:
+         - path: /org.apache.custos.identity.management.service.IdentityManagementService(/|$)(.*)
+           backend:
+              serviceName: identity-management-service
+              servicePort: grpc
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/ingress.yaml b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..078bfee
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
+kind: Ingress
+metadata:
+  name: ${artifactId}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /identity-management/$2
+    cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /identity-management(/|$)(.*)
+            backend:
+              serviceName: identity-management-service
+              servicePort: envoyhttp
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/service.yaml b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..d1e773a
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,33 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  annotations:
+    getambassador.io/config: |
+      ---
+      apiVersion: ambassador/v1
+      kind: Mapping
+      name: tenant-management-service-mapping
+      prefix: /tenant-management/
+      rewrite: ""
+      service: tenant-management-service.custos:50000
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.grpcport }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+    - port: {{ .Values.proxy.port }}
+      targetPort: envoyhttp
+      protocol: TCP
+      name: envoyhttp
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/serviceaccount.yaml b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/tests/test-connection.yaml b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/values.yaml b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..b79f6ef
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/helm/values.yaml
@@ -0,0 +1,85 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+proxy:
+   repository: apachecustos/identity-management-service-sidecar
+   tag: 1.0-SNAPSHOT
+   port: 50000
+   adminport: 9901
+
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
\ No newline at end of file
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/IdentityManagementServiceInitializer.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/IdentityManagementServiceInitializer.java
new file mode 100644
index 0000000..305c78f
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/IdentityManagementServiceInitializer.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.management;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ClientInterceptor;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.identity.management.interceptors.AgentAuthInterceptor;
+import org.apache.custos.identity.management.interceptors.AuthInterceptorImpl;
+import org.apache.custos.identity.management.interceptors.InputValidator;
+import org.apache.custos.identity.management.interceptors.ResponseInterceptor;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
+import org.apache.custos.integration.services.commons.interceptors.LoggingInterceptor;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+import java.util.Stack;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "org.apache.custos")
+public class IdentityManagementServiceInitializer {
+
+    public static void main(String[] args) {
+        SpringApplication.run(IdentityManagementServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        //   Tracing tracing1 =  Tracing.newBuilder().build();
+        return GrpcTracing.create(tracing);
+    }
+
+    //We also create a client-side interceptor and put that in the context, this interceptor can then be injected into gRPC clients and
+    //then applied to the managed channel.
+    @Bean
+    ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newClientInterceptor();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public Stack<IntegrationServiceInterceptor> getInterceptorSet(AuthInterceptorImpl authInterceptor, InputValidator validator,
+                                                                  AgentAuthInterceptor agentAuthInterceptor, LoggingInterceptor loggingInterceptor) {
+        Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
+        interceptors.add(validator);
+        interceptors.add(authInterceptor);
+        interceptors.add(agentAuthInterceptor);
+        interceptors.add(loggingInterceptor);
+
+        return interceptors;
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(Stack<IntegrationServiceInterceptor> integrationServiceInterceptors) {
+        return new ServiceInterceptor(integrationServiceInterceptors);
+    }
+
+
+
+}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AgentAuthInterceptor.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AgentAuthInterceptor.java
new file mode 100644
index 0000000..155c402
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AgentAuthInterceptor.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.management.service.EndSessionRequest;
+import org.apache.custos.identity.management.service.GetAgentTokenRequest;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for authorize agent specific methods
+ */
+@Component
+public class AgentAuthInterceptor extends AuthInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AgentAuthInterceptor.class);
+
+    public AgentAuthInterceptor(CredentialStoreServiceClient credentialStoreServiceClient,
+                                TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        if (method.equals("getAgentToken")) {
+            AuthClaim claim = authorizeUsingAgentBasicToken(headers, ((GetAgentTokenRequest) msg).getClientId());
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            GetAgentTokenRequest reqCore =
+                    ((GetAgentTokenRequest) msg).toBuilder()
+                            .setTenantId(claim.getTenantId())
+                            .setAgentClientId(claim.getAgentClientId())
+                            .setAgentClientSecret(claim.getAgentClientSecret())
+                            .setAgentId(claim.getAgentId())
+                            .setAgentPassword(claim.getAgentPassword())
+                            .build();
+
+            return (ReqT) reqCore;
+        } else if (method.equals("endAgentSession")) {
+            LOGGER.info("ClientId " + ((EndSessionRequest) msg).getClientId());
+            AuthClaim claim = authorizeUsingAgentBasicToken(headers, ((EndSessionRequest) msg).getClientId());
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+
+            org.apache.custos.identity.service.EndSessionRequest endSessionRequest =
+                    ((EndSessionRequest) msg).getBody().toBuilder()
+                            .setClientId(claim.getAgentClientId())
+                            .setClientSecret(claim.getAgentClientSecret())
+                            .setTenantId(claim.getTenantId())
+                            .build();
+            return (ReqT) ((EndSessionRequest) msg).toBuilder().setBody(endSessionRequest).build();
+
+        }
+        return msg;
+
+    }
+}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AuthInterceptorImpl.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AuthInterceptorImpl.java
new file mode 100644
index 0000000..416b79c
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/AuthInterceptorImpl.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.credential.store.service.Credentials;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.management.service.EndSessionRequest;
+import org.apache.custos.identity.management.service.GetCredentialsRequest;
+import org.apache.custos.identity.management.utils.Constants;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.identity.service.AuthenticationRequest;
+import org.apache.custos.identity.service.Claim;
+import org.apache.custos.identity.service.GetTokenRequest;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.MultiTenantAuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for managing auth flow
+ */
+@Component
+public class AuthInterceptorImpl extends MultiTenantAuthInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AuthInterceptorImpl.class);
+
+    @Autowired
+    public AuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT reqT) {
+
+        if (method.equals("authorize") || method.equals("getAgentToken") || method.equals("endAgentSession")) {
+
+            return reqT;
+        }
+
+
+        if (method.equals("authenticate")) {
+            AuthClaim claim = authorize(headers);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            AuthenticationRequest reqCore =
+                    ((AuthenticationRequest) reqT).toBuilder()
+                            .setTenantId(claim.getTenantId())
+                            .setClientId(claim.getIamAuthId())
+                            .setClientSecret(claim.getIamAuthSecret())
+                            .build();
+
+            return (ReqT) reqCore;
+        } else if (method.equals("isAuthenticated")) {
+            AuthClaim claim = authorize(headers);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String accessToken = ((AuthToken) reqT).getAccessToken();
+
+            AuthToken.Builder authzBuilder = AuthToken.newBuilder()
+                    .setAccessToken(accessToken);
+
+            String username = null;
+
+            for (Claim claims : ((AuthToken) reqT).getClaimsList()) {
+                if (claims.getKey().equals("username")) {
+                    username = claims.getValue();
+                }
+            }
+            Claim userClaim = Claim.newBuilder().setKey("username").setValue(username).build();
+
+            Claim tenantClaim = Claim.newBuilder().setKey("tenantId").setValue(String.valueOf(claim.getTenantId())).build();
+
+            authzBuilder.addClaims(userClaim);
+            authzBuilder.addClaims(tenantClaim);
+
+            return (ReqT) authzBuilder.build();
+
+
+        } else if (method.equals("getUser")) {
+
+            AuthToken authToken = ((AuthToken) reqT);
+            String clientId = null;
+            for (Claim claim : authToken.getClaimsList()) {
+                if (claim.getKey().equals(Constants.CLIENT_ID)) {
+                    clientId = claim.getValue();
+                }
+            }
+
+            String username = null;
+            for (Claim claims : ((AuthToken) reqT).getClaimsList()) {
+                if (claims.getKey().equals("username")) {
+                    username = claims.getValue();
+                }
+            }
+
+            String accessToken = ((AuthToken) reqT).getAccessToken();
+            AuthToken.Builder authzBuilder = AuthToken.newBuilder()
+                    .setAccessToken(accessToken);
+            AuthClaim claim = authorize(headers, clientId);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            long tenantId = claim.getTenantId();
+
+            Claim userClaim = Claim.newBuilder().setKey("username").setValue(username).build();
+            Claim tenantClaim = Claim.newBuilder().setKey("tenantId").setValue(String.valueOf(tenantId)).build();
+            authzBuilder.addClaims(userClaim);
+            authzBuilder.addClaims(tenantClaim);
+
+            return (ReqT) authzBuilder.build();
+        } else if (method.equals("getUserManagementServiceAccountAccessToken")) {
+            AuthClaim claim = authorize(headers);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            org.apache.custos.identity.service.GetUserManagementSATokenRequest request =
+                    org.apache.custos.identity.service.GetUserManagementSATokenRequest
+                            .newBuilder()
+                            .setTenantId(claim.getTenantId())
+                            .setClientId(claim.getIamAuthId())
+                            .setClientSecret(claim.getIamAuthSecret())
+                            .build();
+            return (ReqT) request;
+
+        } else if (method.equals("token")) {
+            AuthClaim claim = authorize(headers);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            GetTokenRequest request = ((GetTokenRequest) reqT).toBuilder()
+                    .setTenantId(claim.getTenantId())
+                    .setClientId(claim.getIamAuthId())
+                    .setClientSecret(claim.getIamAuthSecret())
+                    .build();
+            return (ReqT) request;
+
+        } else if (method.equals("getCredentials")) {
+            AuthClaim claim = authorize(headers);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            Credentials credentials = Credentials.newBuilder()
+                    .setCustosClientId(claim.getCustosId())
+                    .setCustosClientSecret(claim.getCustosSecret())
+                    .setCustosClientIdIssuedAt(claim.getCustosIdIssuedAt())
+                    .setCustosClientSecretExpiredAt(claim.getCustosSecretExpiredAt())
+                    .setCiLogonClientId(claim.getCiLogonId())
+                    .setCiLogonClientSecret(claim.getCiLogonSecret())
+                    .setIamClientId(claim.getIamAuthId())
+                    .setIamClientSecret(claim.getIamAuthSecret())
+                    .build();
+
+            return (ReqT) ((GetCredentialsRequest) reqT).toBuilder().setCredentials(credentials).build();
+
+        } else if (method.equals("endUserSession")) {
+            AuthClaim claim = authorize(headers);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            org.apache.custos.identity.service.EndSessionRequest endSessionRequest =
+                    ((EndSessionRequest) reqT).getBody().toBuilder()
+                            .setClientId(claim.getIamAuthId())
+                            .setClientSecret(claim.getIamAuthSecret())
+                            .setTenantId(claim.getTenantId())
+                            .build();
+            return (ReqT) ((EndSessionRequest) reqT).toBuilder().setBody(endSessionRequest).build();
+
+        }
+
+        return reqT;
+    }
+}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/InputValidator.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/InputValidator.java
new file mode 100644
index 0000000..9ce7a78
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/InputValidator.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.identity.management.service.AuthorizationRequest;
+import org.apache.custos.identity.management.service.GetAgentTokenRequest;
+import org.apache.custos.identity.management.service.GetCredentialsRequest;
+import org.apache.custos.identity.management.utils.Constants;
+import org.apache.custos.identity.service.GetOIDCConfiguration;
+import org.apache.custos.integration.core.exceptions.MissingParameterException;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class InputValidator implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        switch (method) {
+            case "authorize":
+                validateAuthorize(headers, msg, method);
+                break;
+            case "getOIDCConfiguration":
+                validationGetOIDCConfiguration(headers, msg, method);
+                break;
+
+            case "getCredentials":
+                validationGetCredentials(headers, msg, method);
+                break;
+
+            case "getAgentToken":
+                validateGetAgentToken(headers, msg, method);
+                break;
+            case "endAgentSession":
+                validationAuthorizationHeader(headers);
+            default:
+        }
+        return msg;
+    }
+
+
+    private boolean validateAuthorize(Metadata headers, Object body, String method) {
+
+        if (body == null || !(body instanceof AuthorizationRequest)) {
+
+            AuthorizationRequest request = (AuthorizationRequest) body;
+
+            if (request.getResponseType() == null || !request.getResponseType().trim().equals(Constants.AUTHORIZATION_CODE)) {
+                throw new MissingParameterException("Incorrect response type", null);
+            }
+            if (request.getClientId() == null || !request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("ClientId is not available", null);
+            }
+            if (request.getRedirectUri() == null || request.getRedirectUri().trim().equals("")) {
+                throw new MissingParameterException("redirectUri is not available", null);
+            }
+            if (request.getScope() == null || request.getScope().trim().equals("")) {
+                throw new MissingParameterException("scope is not available", null);
+            }
+
+
+        }
+        return true;
+    }
+
+
+    private boolean validateGetAgentToken(Metadata headers, Object body, String method) {
+        validationAuthorizationHeader(headers);
+
+            GetAgentTokenRequest request = (GetAgentTokenRequest) body;
+
+            if (request.getClientId() == null || request.getClientId().trim().equals("")) {
+                throw new MissingParameterException("ClientId is not available", null);
+            } if (request.getGrantType() == null || !(request.getGrantType().equals(Constants.CLIENT_CREDENTIALS) ||
+                    request.getGrantType().equals(Constants.REFERESH_TOKEN))) {
+                throw new MissingParameterException("Grant type should not be null", null);
+            }
+
+        return true;
+    }
+
+
+    private boolean validationAuthorizationHeader(Metadata headers) {
+        if (headers.get(Metadata.Key.of(Constants.AUTHORIZATION_HEADER, Metadata.ASCII_STRING_MARSHALLER)) == null) {
+            throw new MissingParameterException("authorization header not available", null);
+        }
+
+        return true;
+    }
+
+
+    private boolean validationGetOIDCConfiguration(Metadata headers, Object body, String method) {
+        if (body instanceof GetOIDCConfiguration) {
+            GetOIDCConfiguration configuration = (GetOIDCConfiguration) body;
+            if (configuration.getClientId() == null || configuration.getClientId().equals("")) {
+                throw new MissingParameterException("Client Id  is not available", null);
+            }
+        }
+
+        return true;
+    }
+
+    private boolean validationGetCredentials(Metadata headers, Object body, String method) {
+        if (body instanceof GetCredentialsRequest) {
+            GetCredentialsRequest configuration = (GetCredentialsRequest) body;
+            if (configuration.getClientId() == null || configuration.getClientId().equals("")) {
+                throw new MissingParameterException("Client Id  is not available", null);
+            }
+        }
+
+        return true;
+    }
+
+}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/ResponseInterceptor.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/ResponseInterceptor.java
new file mode 100644
index 0000000..1727b91
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/interceptors/ResponseInterceptor.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.management.interceptors;
+
+import io.grpc.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+public class ResponseInterceptor implements ServerInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ResponseInterceptor.class);
+
+    @Override
+    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata,
+                                                                 ServerCallHandler<ReqT, RespT> serverCallHandler) {
+
+        LOGGER.info("right now calling");
+        return serverCallHandler.startCall(new ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(serverCall) {
+
+
+            @Override
+            public void sendHeaders(Metadata responseHeaders) {
+                Metadata.Key<String> CUSTOM_HEADER_KEY =
+                        Metadata.Key.of("Location", Metadata.ASCII_STRING_MARSHALLER);
+                Metadata.Key<String> HEADER_KEY =
+                        Metadata.Key.of("grpc-status", Metadata.ASCII_STRING_MARSHALLER);
+                responseHeaders.put(CUSTOM_HEADER_KEY, "https://location.com");
+                responseHeaders.put(HEADER_KEY, "302");
+                LOGGER.info("Header Location" + "settet");
+
+                Set<String> keys = responseHeaders.keys();
+
+                for (String key : keys) {
+                    LOGGER.info("Key " + key);
+                    Metadata.Key<String> KEY =
+                            Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER);
+                    LOGGER.info("Value " + responseHeaders.get(KEY));
+                }
+
+                super.sendHeaders(responseHeaders);
+            }
+
+        }, metadata);
+    }
+}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/service/IdentityManagementService.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/service/IdentityManagementService.java
new file mode 100644
index 0000000..80e0ec6
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/service/IdentityManagementService.java
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.management.service;
+
+import com.google.protobuf.Struct;
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.credential.store.service.CredentialMetadata;
+import org.apache.custos.credential.store.service.Credentials;
+import org.apache.custos.credential.store.service.GetCredentialRequest;
+import org.apache.custos.credential.store.service.Type;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.management.utils.Constants;
+import org.apache.custos.identity.service.*;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.tenant.profile.service.GetTenantRequest;
+import org.apache.custos.tenant.profile.service.GetTenantResponse;
+import org.apache.custos.tenant.profile.service.Tenant;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * The grpc service class to use for Identity management related services
+ */
+@GRpcService
+public class IdentityManagementService extends IdentityManagementServiceGrpc.IdentityManagementServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(IdentityManagementService.class);
+
+    @Autowired
+    private IdentityClient identityClient;
+
+    @Autowired
+    private TenantProfileClient tenantProfileClient;
+
+    @Autowired
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+    @Override
+    public void authenticate(AuthenticationRequest request, StreamObserver<AuthToken> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to authenticate for " + request.getUsername());
+
+            AuthToken authzToken = identityClient.authenticate(request);
+
+            responseObserver.onNext(authzToken);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while authentication " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void getUser(AuthToken request, StreamObserver<User> responseObserver) {
+        try {
+            LOGGER.debug("Request received  for getUser");
+            User user = identityClient.getUser(request);
+            responseObserver.onNext(user);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void getUserManagementServiceAccountAccessToken(GetUserManagementSATokenRequest request, StreamObserver<AuthToken> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to authenticate for " + request.getTenantId());
+
+            AuthToken token = identityClient.getUserManagementSATokenRequest(request);
+            responseObserver.onNext(token);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching service account " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void isAuthenticated(AuthToken request, StreamObserver<IsAuthenticateResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to isAuthenticated ");
+            IsAuthenticateResponse response = identityClient.isAuthenticated(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching authenticated status " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void authorize(AuthorizationRequest request, StreamObserver<AuthorizationResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to authorize " + request.getClientId());
+
+
+            GetCredentialRequest req = GetCredentialRequest.newBuilder().setId(request.getClientId()).build();
+
+            CredentialMetadata metadata = credentialStoreServiceClient.getCustosCredentialFromClientId(req);
+
+
+            req = req.toBuilder().setType(Type.IAM).setOwnerId(metadata.getOwnerId()).build();
+
+            CredentialMetadata iamMetadata = credentialStoreServiceClient.getCredential(req);
+
+
+            GetTenantRequest tenantRequest = GetTenantRequest.newBuilder().setTenantId(metadata.getOwnerId()).build();
+
+            GetTenantResponse tenantResponse = tenantProfileClient.getTenant(tenantRequest);
+
+            Tenant tenant = tenantResponse.getTenant();
+
+            if (tenant.getRedirectUrisList() == null || tenant.getRedirectUrisCount() == 0) {
+                responseObserver.onError(Status.INVALID_ARGUMENT.
+                        withDescription("Wrong redirect_uri").asRuntimeException());
+                return;
+            }
+
+            boolean matched = false;
+
+            for (String redireURI : tenant.getRedirectUrisList()) {
+                if (request.getRedirectUri().equals(redireURI)) {
+                    matched = true;
+                    break;
+                }
+            }
+
+            if (!matched) {
+                responseObserver.onError(Status.INVALID_ARGUMENT.
+                        withDescription("Wrong redirect_uri").asRuntimeException());
+                return;
+            }
+
+            GetAuthorizationEndpointRequest getAuthorizationEndpointRequest = GetAuthorizationEndpointRequest
+                    .newBuilder()
+                    .setTenantId(metadata.getOwnerId()).build();
+
+            org.apache.custos.identity.service.AuthorizationResponse response =
+                    identityClient.getAuthorizationEndpoint(getAuthorizationEndpointRequest);
+
+            String endpoint = response.getAuthorizationEndpoint();
+
+
+            String loginURL = endpoint + "?" + "client_id=" + iamMetadata.getId() + "&" + "redirect_uri="
+                    + request.getRedirectUri() + "&" + "response_type="
+                    + Constants.AUTHORIZATION_CODE + "&" + "scope=" + request.getScope() + "&" + "state=" + request.getState();
+
+            AuthorizationResponse resp = AuthorizationResponse.newBuilder().setLoginURI(loginURL).build();
+
+            responseObserver.onNext(resp);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Exception occurred while formulating login uri " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void token(GetTokenRequest request, StreamObserver<Struct> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to token endpoint " + request.getTenantId());
+
+            Struct response = identityClient.getAccessToken(request);
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while  fetching access token " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void getOIDCConfiguration(GetOIDCConfiguration request, StreamObserver<Struct> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to fetch OIDC configuration " + request.getTenantId());
+
+            String clientId = request.getClientId();
+
+            GetCredentialRequest req = GetCredentialRequest.newBuilder().setId(clientId).build();
+
+
+            CredentialMetadata metadata = credentialStoreServiceClient.getCustosCredentialFromClientId(req);
+
+
+            GetCredentialRequest iamCredentialRequest = GetCredentialRequest.newBuilder().setType(Type.IAM).
+                    setOwnerId(metadata.getOwnerId())
+                    .setId(request.getClientId()).build();
+
+            CredentialMetadata iamCredential = credentialStoreServiceClient.getCredential(iamCredentialRequest);
+
+
+            request = request.toBuilder().setTenantId(metadata.getOwnerId()).setClientId(iamCredential.getId()).build();
+
+            Struct struct = identityClient.getOIDCConfiguration(request);
+
+            responseObserver.onNext(struct);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while  retrieving OIDC configuration " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void getCredentials(GetCredentialsRequest request, StreamObserver<Credentials> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to get Credentials for token " + request.getCredentials().getCustosClientId());
+
+            if (request.getClientId().equals(request.getCredentials().getCustosClientId())) {
+                responseObserver.onNext(request.getCredentials());
+                responseObserver.onCompleted();
+            } else {
+                //TODO : check for child tenant under super tenant
+
+
+            }
+        } catch (Exception ex) {
+            String msg = "Exception occurred while  retrieving Credentials " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void getAgentToken(GetAgentTokenRequest request, StreamObserver<Struct> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to getAgentToken endpoint " + request.getTenantId());
+
+            if (request.getGrantType().equals(Constants.CLIENT_CREDENTIALS)) {
+                GetTokenRequest getTokenRequest = GetTokenRequest.newBuilder()
+                        .setClientId(request.getAgentClientId())
+                        .setClientSecret(request.getAgentClientSecret())
+                        .setPassword(request.getAgentPassword())
+                        .setUsername(request.getAgentId())
+                        .setTenantId(request.getTenantId())
+                        .build();
+                Struct response = identityClient.getTokenByPasswordGrantType(getTokenRequest);
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+
+            } else {
+                GetTokenRequest getTokenRequest = GetTokenRequest.newBuilder()
+                        .setClientId(request.getAgentClientId())
+                        .setClientSecret(request.getAgentClientSecret())
+                        .setRefreshToken(request.getRefreshToken())
+                        .setTenantId(request.getTenantId())
+                        .build();
+                Struct response = identityClient.getTokenByRefreshTokenGrantType(getTokenRequest);
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+
+            }
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while  fetching agent access token " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void endAgentSession(EndSessionRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to endAgentSession endpoint " + request.getBody().getTenantId());
+
+            OperationStatus status = identityClient.endSession(request.getBody());
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while  fetching agent access token " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+
+    @Override
+    public void endUserSession(EndSessionRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received  to endUserSession endpoint " + request.getBody().getTenantId());
+
+            OperationStatus status = identityClient.endSession(request.getBody());
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while  fetching agent access token " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(ex);
+        }
+    }
+}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/utils/Constants.java b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/utils/Constants.java
new file mode 100644
index 0000000..c2b40f8
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/java/org/apache/custos/identity/management/utils/Constants.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.identity.management.utils;
+
+/**
+ * This is constant class use for tenant management service
+ */
+public final class Constants {
+    public static final String SYSTEM = "SYSTEM";
+    public static final String GATEWAY_ADMIN = "GATEWAY_ADMIN";
+    public static final String CLIENT_SECRET_BASIC = "client_secret_basic";
+    public static final String TENANT_BASE_URI = "https://custos.scigap.org:32036/tenant-management/v1.0.0/oauth2/tenant";
+    public static final String AUTHORIZATION_CODE = "code";
+    public static final String AUTHORIZATION_HEADER = "authorization";
+    public static final String CLIENT_CREDENTIALS = "client_credentials";
+    public static final String REFERESH_TOKEN = "refresh_token";
+    public static final String CLIENT_ID = "client_id";
+}
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/proto/IdentityManagementService.proto b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/proto/IdentityManagementService.proto
new file mode 100644
index 0000000..ae10be1
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/proto/IdentityManagementService.proto
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.identity.management.service;
+
+import "google/api/annotations.proto";
+import "IdentityService.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/any.proto";
+import "CredentialStoreService.proto";
+
+
+
+message AuthorizationRequest {
+    int64 tenant_id = 1;
+    string client_id = 2;
+    string client_secret = 3;
+    string redirect_uri = 4;
+    string response_type = 5;
+    string scope = 6;
+    string state = 7;
+}
+
+message AuthorizationResponse {
+    string loginURI = 1;
+}
+
+message GetCredentialsRequest {
+    string client_id = 1;
+    org.apache.custos.credential.store.service.Credentials credentials = 2;
+}
+
+
+message GetAgentTokenRequest {
+    int64 tenant_id = 1;
+    string agent_client_id = 2;
+    string agent_client_secret = 3;
+    string agentId = 4;
+    string agentPassword = 5;
+    string  client_id = 6;
+    string grant_type = 7;
+    string refresh_token = 8;
+}
+
+message EndSessionRequest {
+    string client_id = 1;
+    org.apache.custos.identity.service.EndSessionRequest body = 2;
+}
+
+
+
+
+service IdentityManagementService {
+
+    rpc authenticate (org.apache.custos.identity.service.AuthenticationRequest) returns (org.apache.custos.identity.service.AuthToken) {
+        option (google.api.http) = {
+           post: "/identity-management/v1.0.0/authenticate"
+         };
+    }
+
+    rpc isAuthenticated (org.apache.custos.identity.service.AuthToken) returns (org.apache.custos.identity.service.IsAuthenticateResponse) {
+        option (google.api.http) = {
+           get: "/identity-management/v1.0.0/authenticate/status"
+         };
+    }
+
+    rpc getUser (org.apache.custos.identity.service.AuthToken) returns (org.apache.custos.identity.service.User) {
+
+        option (google.api.http) = {
+           get: "/identity-management/v1.0.0/user"
+         };
+
+
+    }
+    rpc getUserManagementServiceAccountAccessToken (org.apache.custos.identity.service.GetUserManagementSATokenRequest) returns (org.apache.custos.identity.service.AuthToken) {
+        option (google.api.http) = {
+           get: "/identity-management/v1.0.0/account/token"
+
+         };
+
+    }
+
+    rpc endUserSession(EndSessionRequest) returns (org.apache.custos.identity.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/identity-management/v1.0.0/user/logout"
+           body: "body"
+         };
+    }
+
+    rpc authorize (AuthorizationRequest) returns (AuthorizationResponse) {
+        option (google.api.http) = {
+           get: "/identity-management/v1.0.0/authorize"
+
+         };
+    }
+
+
+    rpc token (org.apache.custos.identity.service.GetTokenRequest) returns (google.protobuf.Struct) {
+        option (google.api.http) = {
+           post: "/identity-management/v1.0.0/token"
+
+         };
+    }
+
+    rpc getCredentials (GetCredentialsRequest) returns (org.apache.custos.credential.store.service.Credentials) {
+        option (google.api.http) = {
+           get: "/identity-management/v1.0.0/credentials"
+        };
+    }
+
+
+
+    rpc getOIDCConfiguration(org.apache.custos.identity.service.GetOIDCConfiguration) returns (google.protobuf.Struct) {
+        option (google.api.http) = {
+           get: "/identity-management/v1.0.0/.well-known/openid-configuration"
+         };
+    }
+
+
+    rpc getAgentToken(GetAgentTokenRequest) returns (google.protobuf.Struct) {
+        option (google.api.http) = {
+           post: "/identity-management/v1.0.0/agent/token/{client_id}"
+         };
+    }
+
+    rpc endAgentSession(EndSessionRequest) returns (org.apache.custos.identity.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/identity-management/v1.0.0/agent/logout/{client_id}"
+           body: "body"
+         };
+    }
+}
\ No newline at end of file
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/resources/application.properties b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/resources/application.properties
new file mode 100644
index 0000000..f63fe56
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/resources/application.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+server.port=8080
+grpc.port=7000
+spring.application.name=identityManagementService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
diff --git a/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/resources/bootstrap.properties b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/identity-management-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default
diff --git a/custos-integration-services/identity-management-service-parent/pom.xml b/custos-integration-services/identity-management-service-parent/pom.xml
new file mode 100644
index 0000000..5f83745
--- /dev/null
+++ b/custos-integration-services/identity-management-service-parent/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>identity-management-service-parent</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>identity-management-service</module>
+        <module>identity-management-service-sidecar</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/log-management-service-parent/log-management-service-sidecar/Dockerfile b/custos-integration-services/log-management-service-parent/log-management-service-sidecar/Dockerfile
new file mode 100644
index 0000000..ed332a2
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service-sidecar/Dockerfile
@@ -0,0 +1,3 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/log-management-service.pb /data/log-management-service.pb
+COPY src/main/resources/envoy.yaml  /etc/envoy/envoy.yaml
diff --git a/custos-integration-services/log-management-service-parent/log-management-service-sidecar/pom.xml b/custos-integration-services/log-management-service-parent/log-management-service-sidecar/pom.xml
new file mode 100644
index 0000000..49911b6
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service-sidecar/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>log-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>log-management-service-sidecar</artifactId>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/log-management-service-parent/log-management-service-sidecar/src/main/resources/envoy.yaml b/custos-integration-services/log-management-service-parent/log-management-service-sidecar/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..a5fb778
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service-sidecar/src/main/resources/envoy.yaml
@@ -0,0 +1,47 @@
+admin:
+  access_log_path: /tmp/admin_access.log
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+  listeners:
+    - name: main-listener
+      address:
+        socket_address: { address: 0.0.0.0, port_value: 50000 }
+      filter_chains:
+        - filters:
+            - name: envoy.http_connection_manager
+              config:
+                stat_prefix: grpc_json
+                codec_type: AUTO
+                route_config:
+                  name: local_route
+                  virtual_hosts:
+                    - name: local_service
+                      domains: ["*"]
+                      routes:
+                        - match: { prefix: "/", grpc: {} }
+                          route: { cluster: grpc-backend-services, timeout: { seconds: 60 } }
+                http_filters:
+                  - name: envoy.grpc_json_transcoder
+                    config:
+                      proto_descriptor: "/data/log-management-service.pb"
+                      services: ["org.apache.custos.log.management.service.LogManagementService"]
+                      convert_grpc_status: true
+                      print_options:
+                        add_whitespace: true
+                        always_print_primitive_fields: true
+                        always_print_enums_as_ints: false
+                        preserve_proto_field_names: true
+                  - name: envoy.router
+  clusters:
+    - name: grpc-backend-services
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: localhost
+            port_value: 7000
diff --git a/custos-integration-services/log-management-service-parent/log-management-service-sidecar/src/main/resources/log-management-service.pb b/custos-integration-services/log-management-service-parent/log-management-service-sidecar/src/main/resources/log-management-service.pb
new file mode 100644
index 0000000..2a0af89
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service-sidecar/src/main/resources/log-management-service.pb
Binary files differ
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/Dockerfile b/custos-integration-services/log-management-service-parent/log-management-service/Dockerfile
new file mode 100644
index 0000000..6457ff8
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/pom.xml b/custos-integration-services/log-management-service-parent/log-management-service/pom.xml
new file mode 100644
index 0000000..b1392ad
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/pom.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>log-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>log-management-service</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>iam-admin-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>federated-authentication-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>cluster-management-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>resource-secret-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-logging-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.api.grpc</groupId>
+            <artifactId>proto-google-common-protos</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.kubernetes</groupId>
+            <artifactId>client-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-logging-client-stub</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/.helmignore b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/Chart.yaml b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..f3c727f
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos log management service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/NOTES.txt b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/_helpers.tpl b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/deployment.yaml b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..a0957f6
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,78 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+            - name: grpc
+              containerPort: {{ .Values.service.grpcport }}
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: {{ .Values.service.port }}
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+        - name: {{ .Chart.Name }}-envoy-proxy
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.proxy.repository }}:{{ .Values.proxy.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: envoyhttp
+              containerPort: {{ .Values.proxy.port }}
+              protocol: TCP
+            - name: adminhttp
+              containerPort: {{ .Values.proxy.adminport }}
+              protocol: TCP
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/ingress-grpc.yaml b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/ingress-grpc.yaml
new file mode 100644
index 0000000..aa95840
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/ingress-grpc.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: "nginx"
+    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
+    cert-manager.io/cluster-issuer: letsencrypt-production
+  name: ${artifactId}-ingress-grpc
+spec:
+  rules:
+     - host: custos.scigap.org
+       http:
+        paths:
+          - path: /org.apache.custos.log.management.service.LogManagementService(/|$)(.*)
+            backend:
+              serviceName: log-management-service
+              servicePort: grpc
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/ingress.yaml b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..708e8ab
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
+kind: Ingress
+metadata:
+  name: ${artifactId}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /log-management/$2
+    cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /log-management(/|$)(.*)
+            backend:
+              serviceName: log-management-service
+              servicePort: envoyhttp
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/service.yaml b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..d1e773a
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,33 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  annotations:
+    getambassador.io/config: |
+      ---
+      apiVersion: ambassador/v1
+      kind: Mapping
+      name: tenant-management-service-mapping
+      prefix: /tenant-management/
+      rewrite: ""
+      service: tenant-management-service.custos:50000
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.grpcport }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+    - port: {{ .Values.proxy.port }}
+      targetPort: envoyhttp
+      protocol: TCP
+      name: envoyhttp
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/serviceaccount.yaml b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/tests/test-connection.yaml b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/values.yaml b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..9bbe139
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/helm/values.yaml
@@ -0,0 +1,90 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+role:
+  name: resource-fetch
+  binding: resource-role-binder
+
+
+proxy:
+   repository: apachecustos/log-management-service-sidecar
+   tag: 1.0-SNAPSHOT
+   port: 50000
+   webport: 50001
+   adminport: 9901
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/LogManagementServiceInitializer.java b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/LogManagementServiceInitializer.java
new file mode 100644
index 0000000..362d9b1
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/LogManagementServiceInitializer.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.log.management;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ClientInterceptor;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
+import org.apache.custos.integration.services.commons.interceptors.LoggingInterceptor;
+import org.apache.custos.log.management.interceptors.ClientAuthInterceptorImpl;
+import org.apache.custos.log.management.interceptors.InputValidator;
+import org.apache.custos.log.management.interceptors.UserAuthInterceptorImpl;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+import java.util.Stack;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "org.apache.custos")
+public class LogManagementServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(LogManagementServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        //   Tracing tracing1 =  Tracing.newBuilder().build();
+        return GrpcTracing.create(tracing);
+    }
+
+    //We also create a client-side interceptor and put that in the context, this interceptor can then be injected into gRPC clients and
+    //then applied to the managed channel.
+    @Bean
+    ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newClientInterceptor();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public Stack<IntegrationServiceInterceptor> getInterceptorSet(InputValidator inputValidator,
+                                                                  ClientAuthInterceptorImpl authInterceptor,
+                                                                  UserAuthInterceptorImpl userAuthInterceptor,
+                                                                  LoggingInterceptor loggingInterceptor) {
+        Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
+        interceptors.add(inputValidator);
+        interceptors.add(authInterceptor);
+        interceptors.add(userAuthInterceptor);
+        interceptors.add(loggingInterceptor);
+        return interceptors;
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(Stack<IntegrationServiceInterceptor> integrationServiceInterceptors) {
+        return new ServiceInterceptor(integrationServiceInterceptors);
+    }
+}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/interceptors/ClientAuthInterceptorImpl.java b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/interceptors/ClientAuthInterceptorImpl.java
new file mode 100644
index 0000000..4daee2e
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/interceptors/ClientAuthInterceptorImpl.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.log.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.MultiTenantAuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.logging.service.LogEventRequest;
+import org.apache.custos.logging.service.LoggingConfigurationRequest;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate confidential client specific authorization.
+ * Methods which authenticates based only on client are implemented here.
+ */
+@Component
+public class ClientAuthInterceptorImpl extends MultiTenantAuthInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+    @Autowired
+    public ClientAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT reqT) {
+
+
+        if (method.equals("getLogEvents")) {
+            LogEventRequest request = (LogEventRequest) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+
+            long tenantId = claim.getTenantId();
+            return (ReqT) ((LogEventRequest) reqT).toBuilder()
+                    .setClientId(oauthId)
+                    .setTenantId(tenantId)
+                    .build();
+
+        } else if (method.equals("isLogEnabled")) {
+
+            LoggingConfigurationRequest request = (LoggingConfigurationRequest) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+
+            long tenantId = claim.getTenantId();
+            LoggingConfigurationRequest registerUserRequest =
+                    ((LoggingConfigurationRequest) reqT).toBuilder()
+                            .setTenantId(tenantId)
+                            .setClientId(oauthId)
+                            .build();
+
+            return (ReqT) registerUserRequest;
+        }
+        return reqT;
+    }
+
+}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/interceptors/InputValidator.java b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/interceptors/InputValidator.java
new file mode 100644
index 0000000..ea23a1f
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/interceptors/InputValidator.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.log.management.interceptors;
+
+
+import io.grpc.Metadata;
+import org.apache.custos.integration.core.exceptions.MissingParameterException;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class validates the  request input parameters
+ */
+@Component
+public class InputValidator implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param body
+     * @return
+     */
+    private void validate(String methodName, Object body, Metadata headers) {
+        validationAuthorizationHeader(headers);
+
+    }
+
+
+    private boolean validationAuthorizationHeader(Metadata headers) {
+        if (headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER)) == null
+                || headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)) == null) {
+            throw new MissingParameterException("authorization header not available", null);
+        }
+
+        return true;
+    }
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        validate(method, msg, headers);
+        return msg;
+    }
+}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/interceptors/UserAuthInterceptorImpl.java b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/interceptors/UserAuthInterceptorImpl.java
new file mode 100644
index 0000000..1e403f4
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/interceptors/UserAuthInterceptorImpl.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.log.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.core.utils.Constants;
+import org.apache.custos.integration.services.commons.interceptors.MultiTenantAuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.logging.service.LoggingConfigurationRequest;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate user specific authorization
+ * Methods authenticates users access tokens are implemented here
+ */
+@Component
+public class UserAuthInterceptorImpl extends MultiTenantAuthInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+    @Autowired
+    public UserAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+
+
+        if (method.equals("enable")) {
+            LoggingConfigurationRequest loggingConfigRequest = (LoggingConfigurationRequest) msg;
+            headers = attachUserToken(headers, loggingConfigRequest.getClientId());
+            AuthClaim claim = authorize(headers, loggingConfigRequest.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            if (!claim.isAdmin()) {
+                throw new NotAuthorizedException("Your are not a tenant admin", null);
+            }
+
+            long tenantId = claim.getTenantId();
+
+            return (ReqT) ((LoggingConfigurationRequest) msg).toBuilder()
+                    .setTenantId(tenantId)
+                    .build();
+        }
+        return msg;
+    }
+
+
+    private Metadata attachUserToken(Metadata headers, String clientId) {
+        if (clientId == null || clientId.trim().equals("")) {
+            String formattedUserToken = getToken(headers);
+            headers.put(Metadata.Key.of(Constants.USER_TOKEN, Metadata.ASCII_STRING_MARSHALLER), formattedUserToken);
+            return headers;
+        }
+        return headers;
+    }
+
+
+}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/service/LogManagementService.java b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/service/LogManagementService.java
new file mode 100644
index 0000000..060ce88
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/java/org/apache/custos/log/management/service/LogManagementService.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.log.management.service;
+
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.logging.client.LoggingClient;
+import org.apache.custos.logging.service.LogEvents;
+import org.apache.custos.log.management.service.LogManagementServiceGrpc;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+@GRpcService
+public class LogManagementService extends LogManagementServiceGrpc.LogManagementServiceImplBase {
+    private static final Logger LOGGER = LoggerFactory.getLogger(LogManagementService.class);
+
+    @Autowired
+    private LoggingClient loggingClient;
+
+
+    @Override
+    public void getLogEvents(org.apache.custos.logging.service.LogEventRequest request,
+                             StreamObserver<org.apache.custos.logging.service.LogEvents> responseObserver) {
+        LOGGER.debug("Request received to getLogEvents of tenant  " + request.getTenantId());
+        try {
+            LogEvents logEvents = loggingClient.getLogEvents(request);
+            responseObserver.onNext(logEvents);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling secretes " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void isLogEnabled(org.apache.custos.logging.service.LoggingConfigurationRequest request,
+                             StreamObserver<org.apache.custos.logging.service.Status> responseObserver) {
+        LOGGER.debug("Request received to isLogEnabled of tenant  " + request.getTenantId());
+        try {
+
+            org.apache.custos.logging.service.Status status = loggingClient.isLogEnabled(request);
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling secretes " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void enable(org.apache.custos.logging.service.LoggingConfigurationRequest request,
+                       StreamObserver<org.apache.custos.logging.service.Status> responseObserver) {
+        LOGGER.debug("Request received to enable of tenant  " + request.getTenantId());
+        try {
+
+            org.apache.custos.logging.service.Status status = loggingClient.enable(request);
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling secretes " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+}
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/proto/LogManagementService.proto b/custos-integration-services/log-management-service-parent/log-management-service/src/main/proto/LogManagementService.proto
new file mode 100644
index 0000000..25a5133
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/proto/LogManagementService.proto
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.log.management.service;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/struct.proto";
+import "LoggingService.proto";
+
+
+
+service LogManagementService {
+
+    rpc getLogEvents(org.apache.custos.logging.service.LogEventRequest) returns (org.apache.custos.logging.service.LogEvents) {
+        option (google.api.http) = {
+           get: "/log-management/v1.0.0/logs"
+         };
+    }
+
+    rpc isLogEnabled(org.apache.custos.logging.service.LoggingConfigurationRequest) returns(org.apache.custos.logging.service.Status) {
+        option (google.api.http) = {
+           get: "/log-management/v1.0.0/status"
+         };
+    }
+
+    rpc enable(org.apache.custos.logging.service.LoggingConfigurationRequest) returns (org.apache.custos.logging.service.Status) {
+        option (google.api.http) = {
+           post: "/log-management/v1.0.0/status"
+         };
+    }
+
+}
\ No newline at end of file
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/resources/application.properties b/custos-integration-services/log-management-service-parent/log-management-service/src/main/resources/application.properties
new file mode 100644
index 0000000..7b72b95
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/resources/application.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+server.port=8080
+grpc.port=7000
+spring.application.name=logManagementService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
diff --git a/custos-integration-services/log-management-service-parent/log-management-service/src/main/resources/bootstrap.properties b/custos-integration-services/log-management-service-parent/log-management-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/log-management-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default
diff --git a/custos-integration-services/log-management-service-parent/pom.xml b/custos-integration-services/log-management-service-parent/pom.xml
new file mode 100644
index 0000000..745aae8
--- /dev/null
+++ b/custos-integration-services/log-management-service-parent/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>log-management-service-parent</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>log-management-service</module>
+        <module>log-management-service-sidecar</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/pom.xml b/custos-integration-services/pom.xml
new file mode 100644
index 0000000..3e41b46
--- /dev/null
+++ b/custos-integration-services/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>custos-integration-services</artifactId>
+     <packaging>pom</packaging>
+    <modules>
+        <module>tenant-management-service-parent</module>
+        <module>identity-management-service-parent</module>
+        <module>custos-integration-services-commons</module>
+        <module>user-management-service-parent</module>
+
+        <module>scim-service</module>
+
+        <module>group-management-service-parent</module>
+        <module>agent-management-service-parent</module>
+        <module>resource-secret-management-service-parent</module>
+        <module>sharing-management-service-parent</module>
+        <module>log-management-service-parent</module>
+
+    </modules>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/resource-secret-management-service-parent/pom.xml b/custos-integration-services/resource-secret-management-service-parent/pom.xml
new file mode 100644
index 0000000..a3fe143
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>resource-secret-management-service-parent</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>resource-secret-management-service</module>
+        <module>resource-secret-management-service-sidecar</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/Dockerfile b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/Dockerfile
new file mode 100644
index 0000000..ad4e3ec
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/Dockerfile
@@ -0,0 +1,3 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/resource-secret-management-service.pb /data/resource-secret-management-service.pb
+COPY src/main/resources/envoy.yaml  /etc/envoy/envoy.yaml
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/pom.xml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/pom.xml
new file mode 100644
index 0000000..e9705de
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>resource-secret-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>resource-secret-management-service-sidecar</artifactId>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/src/main/resources/envoy.yaml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..3328570
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/src/main/resources/envoy.yaml
@@ -0,0 +1,47 @@
+admin:
+  access_log_path: /tmp/admin_access.log
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+  listeners:
+    - name: main-listener
+      address:
+        socket_address: { address: 0.0.0.0, port_value: 50000 }
+      filter_chains:
+        - filters:
+            - name: envoy.http_connection_manager
+              config:
+                stat_prefix: grpc_json
+                codec_type: AUTO
+                route_config:
+                  name: local_route
+                  virtual_hosts:
+                    - name: local_service
+                      domains: ["*"]
+                      routes:
+                        - match: { prefix: "/", grpc: {} }
+                          route: { cluster: grpc-backend-services, timeout: { seconds: 60 } }
+                http_filters:
+                  - name: envoy.grpc_json_transcoder
+                    config:
+                      proto_descriptor: "/data/resource-secret-management-service.pb"
+                      services: ["org.apache.custos.resource.secret.management.service.ResourceSecretManagementService"]
+                      convert_grpc_status: true
+                      print_options:
+                        add_whitespace: true
+                        always_print_primitive_fields: true
+                        always_print_enums_as_ints: false
+                        preserve_proto_field_names: true
+                  - name: envoy.router
+  clusters:
+    - name: grpc-backend-services
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: localhost
+            port_value: 7000
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/src/main/resources/resource-secret-management-service.pb b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/src/main/resources/resource-secret-management-service.pb
new file mode 100644
index 0000000..a2e19f0
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service-sidecar/src/main/resources/resource-secret-management-service.pb
Binary files differ
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/Dockerfile b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/Dockerfile
new file mode 100644
index 0000000..6457ff8
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/pom.xml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/pom.xml
new file mode 100644
index 0000000..e4972c4
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/pom.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>resource-secret-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>resource-secret-management-service</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>iam-admin-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>federated-authentication-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>cluster-management-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>resource-secret-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.api.grpc</groupId>
+            <artifactId>proto-google-common-protos</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.kubernetes</groupId>
+            <artifactId>client-java</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/.helmignore b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/Chart.yaml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..ad8c206
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos resource secret management service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/NOTES.txt b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/_helpers.tpl b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/deployment.yaml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..a0957f6
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,78 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+            - name: grpc
+              containerPort: {{ .Values.service.grpcport }}
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: {{ .Values.service.port }}
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+        - name: {{ .Chart.Name }}-envoy-proxy
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.proxy.repository }}:{{ .Values.proxy.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: envoyhttp
+              containerPort: {{ .Values.proxy.port }}
+              protocol: TCP
+            - name: adminhttp
+              containerPort: {{ .Values.proxy.adminport }}
+              protocol: TCP
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/ingress-grpc.yaml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/ingress-grpc.yaml
new file mode 100644
index 0000000..3c97bc2
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/ingress-grpc.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: "nginx"
+    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
+    cert-manager.io/cluster-issuer: letsencrypt-production
+  name: ${artifactId}-ingress-grpc
+spec:
+  rules:
+     - host: custos.scigap.org
+       http:
+        paths:
+          - path: /org.apache.custos.resource.secret.management.service.ResourceSecretManagementService(/|$)(.*)
+            backend:
+              serviceName: resource-secret-management-service
+              servicePort: grpc
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/ingress.yaml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..b71a1d0
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
+kind: Ingress
+metadata:
+  name: ${artifactId}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /resource-secret-management/$2
+    cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /resource-secret-management(/|$)(.*)
+            backend:
+              serviceName: resource-secret-management-service
+              servicePort: envoyhttp
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/service.yaml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..d1e773a
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,33 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  annotations:
+    getambassador.io/config: |
+      ---
+      apiVersion: ambassador/v1
+      kind: Mapping
+      name: tenant-management-service-mapping
+      prefix: /tenant-management/
+      rewrite: ""
+      service: tenant-management-service.custos:50000
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.grpcport }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+    - port: {{ .Values.proxy.port }}
+      targetPort: envoyhttp
+      protocol: TCP
+      name: envoyhttp
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/serviceaccount.yaml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/tests/test-connection.yaml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/values.yaml b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..0928901
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/helm/values.yaml
@@ -0,0 +1,90 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+role:
+  name: resource-fetch
+  binding: resource-role-binder
+
+
+proxy:
+   repository: apachecustos/resource-secret-management-service-sidecar
+   tag: 1.0-SNAPSHOT
+   port: 50000
+   webport: 50001
+   adminport: 9901
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/ResourceSecretManagementInitializer.java b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/ResourceSecretManagementInitializer.java
new file mode 100644
index 0000000..8610dd3
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/ResourceSecretManagementInitializer.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.management;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ClientInterceptor;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
+import org.apache.custos.integration.services.commons.interceptors.LoggingInterceptor;
+import org.apache.custos.resource.secret.management.interceptors.ClientAuthInterceptorImpl;
+import org.apache.custos.resource.secret.management.interceptors.InputValidator;
+import org.apache.custos.resource.secret.management.interceptors.UserAuthInterceptorImpl;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+import java.util.Stack;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "org.apache.custos")
+public class ResourceSecretManagementInitializer {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ResourceSecretManagementInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        //   Tracing tracing1 =  Tracing.newBuilder().build();
+        return GrpcTracing.create(tracing);
+    }
+
+    //We also create a client-side interceptor and put that in the context, this interceptor can then be injected into gRPC clients and
+    //then applied to the managed channel.
+    @Bean
+    ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newClientInterceptor();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public Stack<IntegrationServiceInterceptor> getInterceptorSet(InputValidator validator,
+                                                                  ClientAuthInterceptorImpl authInterceptor,
+                                                                  UserAuthInterceptorImpl userAuthInterceptor,
+                                                                  LoggingInterceptor loggingInterceptor) {
+        Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
+        interceptors.add(validator);
+        interceptors.add(authInterceptor);
+        interceptors.add(userAuthInterceptor);
+        interceptors.add(loggingInterceptor);
+
+        return interceptors;
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(Stack<IntegrationServiceInterceptor> integrationServiceInterceptors) {
+        return new ServiceInterceptor(integrationServiceInterceptors);
+    }
+}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/interceptors/ClientAuthInterceptorImpl.java b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/interceptors/ClientAuthInterceptorImpl.java
new file mode 100644
index 0000000..3ffa22c
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/interceptors/ClientAuthInterceptorImpl.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.GetJWKSRequest;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.MultiTenantAuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.resource.secret.service.*;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate confidential client specific authorization.
+ * Methods which authenticates based only on client are implemented here.
+ */
+@Component
+public class ClientAuthInterceptorImpl extends MultiTenantAuthInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+    @Autowired
+    public ClientAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT reqT) {
+
+        if (method.equals("getSecret")) {
+            AuthClaim claim = authorize(headers);
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            return (ReqT) ((GetSecretRequest) reqT).toBuilder()
+                    .setClientId(oauthId)
+                    .setClientSec(oauthSec)
+                    .setTenantId(tenantId)
+                    .build();
+
+        } else if (method.equals("getJWKS")) {
+            AuthClaim claim = authorize(headers);
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            return (ReqT) ((GetJWKSRequest) reqT).toBuilder()
+                    .setClientId(oauthId)
+                    .setClientSecret(oauthSec)
+                    .setTenantId(tenantId)
+                    .build();
+
+        } else if (method.equals("getAllResourceCredentialSummaries")) {
+            String clientId = ((GetResourceCredentialSummariesRequest) reqT).getClientId();
+
+            AuthClaim claim = authorize(headers, clientId);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            return (ReqT) ((GetResourceCredentialSummariesRequest) reqT).toBuilder().setTenantId(claim.getTenantId()).build();
+
+
+        } else if (method.equals("addSSHCredential")) {
+            String clientId = ((SSHCredential) reqT).getMetadata().getClientId();
+
+            AuthClaim claim = authorize(headers, clientId);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            SecretMetadata metadata = ((SSHCredential) reqT).getMetadata().toBuilder().setTenantId(claim.getTenantId()).build();
+
+            return (ReqT) ((SSHCredential) reqT).toBuilder().setMetadata(metadata).build();
+
+
+        } else if (method.equals("addPasswordCredential")) {
+            String clientId = ((PasswordCredential) reqT).getMetadata().getClientId();
+
+            AuthClaim claim = authorize(headers, clientId);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            SecretMetadata metadata = ((PasswordCredential) reqT).getMetadata().toBuilder().setTenantId(claim.getTenantId()).build();
+
+            return (ReqT) ((PasswordCredential) reqT).toBuilder().setMetadata(metadata).build();
+
+        } else if (method.equals("addCertificateCredential")) {
+            String clientId = ((CertificateCredential) reqT).getMetadata().getClientId();
+
+            AuthClaim claim = authorize(headers, clientId);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            SecretMetadata metadata = ((CertificateCredential) reqT).getMetadata().toBuilder().setTenantId(claim.getTenantId()).build();
+
+            return (ReqT) ((CertificateCredential) reqT).toBuilder().setMetadata(metadata).build();
+
+        } else if (method.equals("getSSHCredential") || method.equals("getPasswordCredential") || method.equals("getCertificateCredential")
+                || method.equals("deleteSSHCredential") || method.equals("deletePWDCredential") || method.equals("deleteCertificateCredential")
+                || method.equals("getResourceCredentialSummary")) {
+            String clientId = ((GetResourceCredentialByTokenRequest) reqT).getClientId();
+
+            AuthClaim claim = authorize(headers, clientId);
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+            return (ReqT) ((GetResourceCredentialByTokenRequest) reqT).toBuilder().setTenantId(claim.getTenantId()).build();
+
+        }
+        return reqT;
+    }
+
+}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/interceptors/InputValidator.java b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/interceptors/InputValidator.java
new file mode 100644
index 0000000..3309950
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/interceptors/InputValidator.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.management.interceptors;
+
+
+import io.grpc.Metadata;
+import org.apache.custos.integration.core.exceptions.MissingParameterException;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.resource.secret.service.CertificateCredential;
+import org.apache.custos.resource.secret.service.PasswordCredential;
+import org.apache.custos.resource.secret.service.SSHCredential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class validates the  request input parameters
+ */
+@Component
+public class InputValidator implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param body
+     * @return
+     */
+    private void validate(String methodName, Object body, Metadata headers) {
+
+        validationAuthorizationHeader(headers);
+    }
+
+
+    private boolean validationAuthorizationHeader(Metadata headers) {
+        if (headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER)) == null
+                || headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)) == null) {
+            throw new MissingParameterException("authorization header not available", null);
+        }
+
+        return true;
+    }
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        validate(method, msg, headers);
+
+        if (method.equals("addSSHCredential") || method.equals("addPasswordCredential")
+                || method.equals("addCertificateCredential")) {
+            validateSecretMetadata(msg, method);
+        }
+        return msg;
+    }
+
+
+    private boolean validateSecretMetadata(Object msg, String method) {
+        if (msg instanceof SSHCredential) {
+            SSHCredential request = (SSHCredential) msg;
+
+            if (request.getMetadata() == null) {
+                throw new MissingParameterException("SecretMetadata should not be null ", null);
+            }
+
+        } else if (msg instanceof PasswordCredential) {
+            PasswordCredential request = (PasswordCredential) msg;
+            if (request.getMetadata() == null) {
+                throw new MissingParameterException("SecretMetadata should not be null ", null);
+            }
+        } else if (msg instanceof CertificateCredential) {
+            CertificateCredential request = (CertificateCredential) msg;
+            if (request.getMetadata() == null) {
+                throw new MissingParameterException("SecretMetadata should not be null ", null);
+            }
+        } else {
+            throw new RuntimeException("Unexpected input type for method  " + method);
+        }
+        return true;
+    }
+
+}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/interceptors/UserAuthInterceptorImpl.java b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/interceptors/UserAuthInterceptorImpl.java
new file mode 100644
index 0000000..87c8765
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/interceptors/UserAuthInterceptorImpl.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate user specific authorization
+ * Methods authenticates users access tokens are implemented here
+ */
+@Component
+public class UserAuthInterceptorImpl extends AuthInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+    @Autowired
+    public UserAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        return msg;
+    }
+
+
+}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/service/ResourceSecretManagementService.java b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/service/ResourceSecretManagementService.java
new file mode 100644
index 0000000..ee48a50
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/java/org/apache/custos/resource/secret/management/service/ResourceSecretManagementService.java
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.resource.secret.management.service;
+
+import com.google.protobuf.Struct;
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.cluster.management.client.ClusterManagementClient;
+import org.apache.custos.cluster.management.service.GetServerCertificateRequest;
+import org.apache.custos.cluster.management.service.GetServerCertificateResponse;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.GetJWKSRequest;
+import org.apache.custos.resource.secret.client.ResourceSecretClient;
+import org.apache.custos.resource.secret.management.service.ResourceSecretManagementServiceGrpc.ResourceSecretManagementServiceImplBase;
+import org.apache.custos.resource.secret.service.*;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+@GRpcService
+public class ResourceSecretManagementService extends ResourceSecretManagementServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ResourceSecretManagementService.class);
+
+    @Autowired
+    private ClusterManagementClient clusterManagementClient;
+
+    @Autowired
+    private IdentityClient identityClient;
+
+    @Autowired
+    private ResourceSecretClient resourceSecretClient;
+
+    @Override
+    public void getSecret(GetSecretRequest request,
+                          StreamObserver<SecretMetadata> responseObserver) {
+        LOGGER.debug("Request received to get secret ");
+        try {
+
+            if (request.getMetadata().getOwnerType() == ResourceOwnerType.CUSTOS &&
+                    request.getMetadata().getResourceType() == ResourceType.SERVER_CERTIFICATE) {
+
+                GetServerCertificateRequest getServerCertificateRequest = GetServerCertificateRequest.newBuilder().build();
+                GetServerCertificateResponse response = clusterManagementClient.getCustosServerCertificate(getServerCertificateRequest);
+
+                SecretMetadata metadata = SecretMetadata.newBuilder().setValue(response.getCertificate()).build();
+                responseObserver.onNext(metadata);
+                responseObserver.onCompleted();
+            } else {
+
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling secretes " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getJWKS(GetJWKSRequest request, StreamObserver<Struct> responseObserver) {
+        LOGGER.debug("Request received to get JWKS " + request.getTenantId());
+        try {
+
+            Struct struct = identityClient.getJWKS(request);
+
+            responseObserver.onNext(struct);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling JWKS " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getResourceCredentialSummary(GetResourceCredentialByTokenRequest request, StreamObserver<SecretMetadata> responseObserver) {
+        LOGGER.debug("Request received to get ResourceCredentialSummary of " + request.getToken());
+        try {
+
+            SecretMetadata metadata = resourceSecretClient.getResourceCredentialSummary(request);
+            responseObserver.onNext(metadata);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching resource credential summary : " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAllResourceCredentialSummaries(GetResourceCredentialSummariesRequest request, StreamObserver<ResourceCredentialSummaries> responseObserver) {
+        LOGGER.debug("Request received to get AllResourceCredentialSummaries in tenant " + request.getTenantId());
+        try {
+
+            ResourceCredentialSummaries response = resourceSecretClient.getAllResourceCredentialSummaries(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching all resource credential summaries : " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addSSHCredential(SSHCredential request, StreamObserver<AddResourceCredentialResponse> responseObserver) {
+        LOGGER.debug("Request received to add SSHCredential ");
+        try {
+
+            AddResourceCredentialResponse response = resourceSecretClient.addSSHCredential(request);
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred whiling saving SSH credentials :  " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addPasswordCredential(PasswordCredential request, StreamObserver<AddResourceCredentialResponse> responseObserver) {
+        LOGGER.debug("Request received to add PasswordCredential ");
+        try {
+
+            AddResourceCredentialResponse response = resourceSecretClient.addPasswordCredential(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred while  saving password credential : " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addCertificateCredential(CertificateCredential request, StreamObserver<AddResourceCredentialResponse> responseObserver) {
+        LOGGER.debug("Request received to add CertificateCredential ");
+        try {
+
+            AddResourceCredentialResponse response = resourceSecretClient.addCertificateCredential(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred while saving  certificate credential : " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+
+    }
+
+    @Override
+    public void getSSHCredential(GetResourceCredentialByTokenRequest request, StreamObserver<SSHCredential> responseObserver) {
+        LOGGER.debug("Request received to get SSHCredential ");
+        try {
+
+            SSHCredential response = resourceSecretClient.getSSHCredential(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching  SSH credentials : " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getPasswordCredential(GetResourceCredentialByTokenRequest request, StreamObserver<PasswordCredential> responseObserver) {
+        LOGGER.debug("Request received to get PasswordCredential " + request.getTenantId());
+        try {
+
+            PasswordCredential response = resourceSecretClient.getPasswordCredential(request);
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred while  fetching password credentials : " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getCertificateCredential(GetResourceCredentialByTokenRequest request, StreamObserver<CertificateCredential> responseObserver) {
+        LOGGER.debug("Request received to get CertificateCredential " + request.getTenantId());
+        try {
+
+            CertificateCredential response = resourceSecretClient.getCertificateCredential(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching  certificate credential : " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteSSHCredential(GetResourceCredentialByTokenRequest request, StreamObserver<ResourceCredentialOperationStatus> responseObserver) {
+        LOGGER.debug("Request received to delete SSHCredential " + request.getTenantId());
+        try {
+
+            ResourceCredentialOperationStatus response = resourceSecretClient.deleteSSHCredential(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting  SSH credential : " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deletePWDCredential(GetResourceCredentialByTokenRequest request, StreamObserver<ResourceCredentialOperationStatus> responseObserver) {
+        LOGGER.debug("Request received to delete PWDCredential " + request.getTenantId());
+        try {
+
+            ResourceCredentialOperationStatus response = resourceSecretClient.deletePWDCredential(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting password credential : " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteCertificateCredential(GetResourceCredentialByTokenRequest request, StreamObserver<ResourceCredentialOperationStatus> responseObserver) {
+        LOGGER.debug("Request received to delete CertificateCredential " + request.getTenantId());
+        try {
+            ResourceCredentialOperationStatus response = resourceSecretClient.deleteCertificateCredential(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting  certificate credential :  " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+}
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/proto/ResourceSecretManagementService.proto b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/proto/ResourceSecretManagementService.proto
new file mode 100644
index 0000000..50ff876
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/proto/ResourceSecretManagementService.proto
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.resource.secret.management.service;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/struct.proto";
+import "ResourceSecretService.proto";
+import "IdentityService.proto";
+
+
+service ResourceSecretManagementService {
+
+    rpc getSecret (org.apache.custos.resource.secret.service.GetSecretRequest) returns (org.apache.custos.resource.secret.service.SecretMetadata) {
+        option (google.api.http) = {
+           get: "/resource-secret-management/v1.0.0/secret"
+         };
+    }
+
+    rpc getJWKS (org.apache.custos.identity.service.GetJWKSRequest) returns (google.protobuf.Struct) {
+        option (google.api.http) = {
+           get: "/resource-secret-management/v1.0.0/openid-connect/certs"
+         };
+    }
+
+    rpc getResourceCredentialSummary (org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest) returns (org.apache.custos.resource.secret.service.SecretMetadata) {
+        option (google.api.http) = {
+           get: "/resource-secret-management/v1.0.0/secret/summary"
+         };
+    }
+    rpc getAllResourceCredentialSummaries (org.apache.custos.resource.secret.service.GetResourceCredentialSummariesRequest) returns (org.apache.custos.resource.secret.service.ResourceCredentialSummaries) {
+        option (google.api.http) = {
+           get: "/resource-secret-management/v1.0.0/secret/summaries"
+         };
+    }
+    rpc addSSHCredential (org.apache.custos.resource.secret.service.SSHCredential) returns (org.apache.custos.resource.secret.service.AddResourceCredentialResponse) {
+        option (google.api.http) = {
+           post: "/resource-secret-management/v1.0.0/secret/ssh"
+         };
+    }
+    rpc addPasswordCredential (org.apache.custos.resource.secret.service.PasswordCredential) returns (org.apache.custos.resource.secret.service.AddResourceCredentialResponse) {
+        option (google.api.http) = {
+           post: "/resource-secret-management/v1.0.0/secret/password"
+         };
+    }
+    rpc addCertificateCredential (org.apache.custos.resource.secret.service.CertificateCredential) returns (org.apache.custos.resource.secret.service.AddResourceCredentialResponse) {
+        option (google.api.http) = {
+           post: "/resource-secret-management/v1.0.0/secret/certificate"
+         };
+    }
+
+    rpc getSSHCredential (org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest) returns (org.apache.custos.resource.secret.service.SSHCredential) {
+        option (google.api.http) = {
+           get: "/resource-secret-management/v1.0.0/secret/ssh"
+         };
+    }
+    rpc getPasswordCredential (org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest) returns (org.apache.custos.resource.secret.service.PasswordCredential) {
+        option (google.api.http) = {
+           get: "/resource-secret-management/v1.0.0/secret/password"
+         };
+    }
+    rpc getCertificateCredential (org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest) returns (org.apache.custos.resource.secret.service.CertificateCredential) {
+        option (google.api.http) = {
+           get: "/resource-secret-management/v1.0.0/secret/certificate"
+         };
+    }
+
+    rpc deleteSSHCredential (org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest) returns (org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus) {
+        option (google.api.http) = {
+           delete: "/resource-secret-management/v1.0.0/secret/ssh"
+         };
+    }
+    rpc deletePWDCredential (org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest) returns (org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus) {
+        option (google.api.http) = {
+           delete: "/resource-secret-management/v1.0.0/secret/password"
+         };
+    }
+    rpc deleteCertificateCredential (org.apache.custos.resource.secret.service.GetResourceCredentialByTokenRequest) returns (org.apache.custos.resource.secret.service.ResourceCredentialOperationStatus) {
+        option (google.api.http) = {
+           delete: "/resource-secret-management/v1.0.0/secret/certificate"
+         };
+    }
+
+}
\ No newline at end of file
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/resources/application.properties b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/resources/application.properties
new file mode 100644
index 0000000..74e6151
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/resources/application.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+server.port=8080
+grpc.port=7000
+spring.application.name=resourceSecretManagementService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
diff --git a/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/resources/bootstrap.properties b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++ b/custos-integration-services/resource-secret-management-service-parent/resource-secret-management-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default
diff --git a/custos-integration-services/scim-service/Dockerfile b/custos-integration-services/scim-service/Dockerfile
new file mode 100644
index 0000000..fdf9c0f
--- /dev/null
+++ b/custos-integration-services/scim-service/Dockerfile
@@ -0,0 +1,6 @@
+FROM openjdk:11-jre-slim
+COPY src/main/resources/custos_user_schema_extention.json /home/ubuntu/schemas/custos_user_schema_extention.json
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/custos-integration-services/scim-service/pom.xml b/custos-integration-services/scim-service/pom.xml
new file mode 100644
index 0000000..0ab3971
--- /dev/null
+++ b/custos-integration-services/scim-service/pom.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>scim-service</artifactId>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-bean-validators</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.xml</groupId>
+            <artifactId>jaxb-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.wso2.charon</groupId>
+            <artifactId>org.wso2.charon3.core</artifactId>
+                        <exclusions>
+                            <exclusion>
+                                <groupId>org.ops4j.pax.logging</groupId>
+                                <artifactId>pax-logging-api</artifactId>
+                            </exclusion>
+                        </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+<!--            <exclusions>-->
+<!--                <exclusion>-->
+<!--                    <groupId>org.springframework.boot</groupId>-->
+<!--                    <artifactId>spring-boot-starter-logging</artifactId>-->
+<!--                </exclusion>-->
+<!--            </exclusions>-->
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>iam-admin-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/scim-service/src/main/helm/.helmignore b/custos-integration-services/scim-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-integration-services/scim-service/src/main/helm/Chart.yaml b/custos-integration-services/scim-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..f52f23d
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos scim service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-integration-services/scim-service/src/main/helm/templates/NOTES.txt b/custos-integration-services/scim-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-integration-services/scim-service/src/main/helm/templates/_helpers.tpl b/custos-integration-services/scim-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-integration-services/scim-service/src/main/helm/templates/deployment.yaml b/custos-integration-services/scim-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..8cc78dc
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,63 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  strategy:
+    type: RollingUpdate
+    rollingUpdate:
+      maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+      maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: {{ .Values.service.port }}
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-integration-services/scim-service/src/main/helm/templates/ingress.yaml b/custos-integration-services/scim-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..5f90e04
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,22 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
+kind: Ingress
+metadata:
+  name: ${artifactId}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /$2
+    kubernetes.io/ingress.class: "nginx"
+    cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /scim(/|$)(.*)
+            backend:
+              serviceName: scim-service
+              servicePort: http
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/scim-service/src/main/helm/templates/service.yaml b/custos-integration-services/scim-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..5752c1d
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,25 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  annotations:
+    getambassador.io/config: |
+      ---
+      apiVersion: ambassador/v1
+      kind: Mapping
+      name: tenant-management-service-mapping
+      prefix: /tenant-management/
+      rewrite: ""
+      service: tenant-management-service.custos:50000
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-integration-services/scim-service/src/main/helm/templates/serviceaccount.yaml b/custos-integration-services/scim-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-integration-services/scim-service/src/main/helm/templates/tests/test-connection.yaml b/custos-integration-services/scim-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-integration-services/scim-service/src/main/helm/values.yaml b/custos-integration-services/scim-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..24389a2
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/helm/values.yaml
@@ -0,0 +1,82 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  #grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
+
+
+
+
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/SCIMServiceInitializer.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/SCIMServiceInitializer.java
new file mode 100644
index 0000000..745e949
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/SCIMServiceInitializer.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "org.apache.custos")
+public class SCIMServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(SCIMServiceInitializer.class, args);
+    }
+}
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/config/Swagger2Config.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/config/Swagger2Config.java
new file mode 100644
index 0000000..144ef1c
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/config/Swagger2Config.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim.config;
+
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class Swagger2Config {
+    @Bean
+    public Docket api() {
+        return new Docket(DocumentationType.SWAGGER_2).select()
+                .apis(RequestHandlerSelectors
+                        .basePackage("org.apache.custos.scim.resource"))
+                .paths(PathSelectors.regex("/.*"))
+                .build().apiInfo(apiEndPointsInfo());
+    }
+
+    private ApiInfo apiEndPointsInfo() {
+        return new ApiInfoBuilder().title("Spring Boot REST API")
+                .description("Custos SCIM REST APIs")
+                .contact(new Contact("Apache Custos", "https://custos.org", "custos@apache.airavata.org"))
+                .license("Apache 2.0")
+                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
+                .version("1.0.0")
+                .build();
+    }
+}
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/AbstractResource.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/AbstractResource.java
new file mode 100644
index 0000000..ea7be8c
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/AbstractResource.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim.resource;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.wso2.charon3.core.protocol.SCIMResponse;
+
+import java.util.Map;
+
+/**
+ * Parent class of all resources
+ */
+public class AbstractResource {
+
+
+    public ResponseEntity buildResponse(SCIMResponse response) {
+
+        if (response != null) {
+            ResponseEntity.BodyBuilder builder = ResponseEntity
+                    .status(response.getResponseStatus());
+
+            Map<String, String> headerMap = response.getHeaderParamMap();
+
+            if (headerMap != null && !headerMap.isEmpty()) {
+                HttpHeaders httpHeaders = new HttpHeaders();
+                for (String key : headerMap.keySet()) {
+                    httpHeaders.set(key, headerMap.get(key));
+                }
+                return builder.headers(httpHeaders).body(response.getResponseMessage());
+            } else {
+                return builder.build();
+            }
+
+
+        } else {
+            ResponseEntity.BodyBuilder builder = ResponseEntity
+                    .status(HttpStatus.ACCEPTED);
+            return builder.build();
+
+        }
+
+    }
+
+}
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/GroupResource.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/GroupResource.java
new file mode 100644
index 0000000..68f1b04
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/GroupResource.java
@@ -0,0 +1,318 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim.resource;
+
+import io.swagger.annotations.*;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.scim.resource.manager.ResourceManager;
+import org.apache.custos.scim.utils.AuthHandler;
+import org.apache.custos.scim.utils.Constants;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.wso2.charon3.core.protocol.SCIMResponse;
+import org.wso2.charon3.core.protocol.endpoints.GroupResourceManager;
+
+import java.util.Map;
+
+@RestController
+@RequestMapping(value = {"/v2/Groups"})
+@Api(value = "Group Resource Management")
+public class GroupResource extends AbstractResource {
+    private final static Logger LOGGER = LoggerFactory.getLogger(GroupResource.class);
+
+    @Autowired
+    private ResourceManager resourceManager;
+
+    @Autowired
+    private AuthHandler authHandler;
+
+    @ApiOperation(
+            value = "Return the group with the given id",
+            notes = "Returns HTTP 200 if the group is found.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "Valid group is found"),
+            @ApiResponse(code = 404, message = "Valid group is not found")})
+
+    @GetMapping(value = {"/{id}"}, produces = {"application/json", "application/scim+json"})
+    public ResponseEntity getGroup(@ApiParam(value = Constants.ID_DESC, required = true)
+                                   @PathVariable(Constants.ID) String id,
+                                   @ApiParam(value = Constants.ATTRIBUTES_DESC, required = false)
+                                   @RequestParam(value = Constants.ATTRIBUTES, required = false) String attribute,
+                                   @ApiParam(value = Constants.EXCLUDED_ATTRIBUTES_DESC, required = false)
+                                   @RequestParam(value =Constants.EXCLUDE_ATTRIBUTES, required = false) String excludedAttributes,
+                                   @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        AuthClaim claim = authHandler.validateAndConfigure(authorizationHeader, false);
+
+        JSONObject newObj = new JSONObject();
+
+        newObj.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        newObj.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        newObj.put(Constants.ID, id);
+        newObj.put(Constants.TENANT_ID, String.valueOf(claim.getTenantId()));
+        newObj.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+
+
+        JSONObject custosExtention = new JSONObject();
+        custosExtention.put(Constants.CUSTOS_EXTENSION, newObj);
+
+        // create charon-SCIM user endpoint and hand-over the request.
+        GroupResourceManager groupResourceManager = new GroupResourceManager();
+
+        SCIMResponse response = groupResourceManager.get(custosExtention.toString(), resourceManager, attribute, excludedAttributes);
+
+        return buildResponse(response);
+
+    }
+
+    @ApiOperation(
+            value = "Return the group which was created",
+            notes = "Returns HTTP 201 if the group is successfully created.")
+    @ApiResponses(value = {
+            @ApiResponse(code = 201, message = "Valid group is created"),
+            @ApiResponse(code = 404, message = "Group is not found")})
+
+    @PostMapping(produces = {"application/json", "application/scim+json"}, consumes = {"application/scim+json"})
+    public ResponseEntity createGroup(@ApiParam(value = Constants.ATTRIBUTES_DESC, required = false)
+                                      @RequestParam(value = Constants.ATTRIBUTES, required = false) String attribute,
+                                      @ApiParam(value = Constants.EXCLUDED_ATTRIBUTES_DESC, required = false)
+                                      @RequestParam(value = Constants.EXCLUDE_ATTRIBUTES, required = false) String excludedAttributes,
+                                      @RequestBody Map<String, Object> payload,
+                                      @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+        AuthClaim claim = authHandler.validateAndConfigure(authorizationHeader, false);
+
+        JSONObject object = new JSONObject(payload);
+
+//        Object custosExtension = object.get(Constants.MEMBERS);
+//
+//        JSONArray cust = null;
+//        if (custosExtension == null) {
+        JSONArray    cust = new JSONArray();
+//        } else if (custosExtension instanceof JSONArray) {
+//            cust = (JSONArray) custosExtension;
+//        }
+
+        JSONObject jsonObject = new JSONObject();
+
+        jsonObject.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        jsonObject.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        jsonObject.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+        jsonObject.put(Constants.TENANT_ID, String.valueOf(claim.getTenantId()));
+
+
+        // create charon-SCIM user endpoint and hand-over the request.
+        GroupResourceManager groupResourceManager = new GroupResourceManager();
+
+        JSONObject member = new JSONObject();
+
+        member.put(Constants.VALUE, jsonObject.toString());
+        member.put("display",Constants.CUSTOS_EXTENSION);
+
+        cust.put(member);
+
+        object.put(Constants.MEMBERS, cust);
+
+
+        SCIMResponse response = groupResourceManager.create(object.toString(), resourceManager,
+                attribute, excludedAttributes);
+
+
+        return buildResponse(response);
+    }
+
+    @ApiOperation(
+            value = "Delete the group with the given id",
+            notes = "Returns HTTP 204 if the group is successfully deleted.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 204, message = "Group is deleted"),
+            @ApiResponse(code = 404, message = "Valid group is not found")})
+
+    @DeleteMapping(value = {"/{id}"}, produces = {"application/json", "application/scim+json"})
+    public ResponseEntity deleteGroup(@ApiParam(value = Constants.ID_DESC, required = true)
+                                      @PathVariable(Constants.ID) String id,
+                                      @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        AuthClaim claim = authHandler.validateAndConfigure(authorizationHeader, false);
+
+
+        JSONObject newObj = new JSONObject();
+
+
+        newObj.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        newObj.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        newObj.put(Constants.ID, id);
+        newObj.put(Constants.TENANT_ID, String.valueOf(claim.getTenantId()));
+        newObj.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+
+
+        JSONObject custosExtention = new JSONObject();
+        custosExtention.put(Constants.CUSTOS_EXTENSION, newObj);
+
+        // create charon-SCIM user endpoint and hand-over the request.
+        GroupResourceManager groupResourceManager = new GroupResourceManager();
+        LOGGER.info("Id Before  " + custosExtention.toString());
+        SCIMResponse response = groupResourceManager.delete(custosExtention.toString(), resourceManager);
+
+        return buildResponse(response);
+    }
+
+    @ApiOperation(
+            value = "Return the updated group",
+            notes = "Returns HTTP 404 if the group is not found.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "Group is updated"),
+            @ApiResponse(code = 404, message = "Valid group is not found")})
+
+    @PutMapping(value = {"/{id}"}, produces = {"application/json", "application/scim+json"}, consumes = {"application/scim+json"})
+    public ResponseEntity updateGroup(@ApiParam(value = Constants.ID_DESC, required = true)
+                                      @PathVariable(Constants.ID) String id,
+                                      @ApiParam(value = Constants.ATTRIBUTES_DESC, required = false)
+                                      @RequestParam(value = Constants.ATTRIBUTES, required = false) String attribute,
+                                      @ApiParam(value = Constants.EXCLUDED_ATTRIBUTES_DESC, required = false)
+                                      @RequestParam(value = Constants.EXCLUDE_ATTRIBUTES, required = false) String excludedAttributes,
+                                      @RequestBody Map<String, Object> payload,
+                                      @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        AuthClaim claim = authHandler.validateAndConfigure(authorizationHeader, false);
+
+        JSONObject object = new JSONObject(payload);
+
+
+
+
+//        Object custosExtension = object.get(Constants.MEMBERS);
+//
+//        JSONArray cust = null;
+//        if (custosExtension == null) {
+        JSONArray    cust = new JSONArray();
+//        } else if (custosExtension instanceof JSONArray) {
+//            cust = (JSONArray) custosExtension;
+//        }
+
+        JSONObject jsonObject = new JSONObject();
+
+        jsonObject.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        jsonObject.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        jsonObject.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+        jsonObject.put(Constants.TENANT_ID, String.valueOf(claim.getTenantId()));
+
+
+        JSONObject member = new JSONObject();
+
+        member.put(Constants.VALUE, jsonObject.toString());
+        member.put("display",Constants.CUSTOS_EXTENSION);
+
+        cust.put(member);
+
+        object.put(Constants.MEMBERS, cust);
+
+
+        JSONObject newObj = new JSONObject();
+
+        newObj.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        newObj.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        newObj.put(Constants.ID, id);
+        newObj.put(Constants.TENANT_ID, String.valueOf(claim.getTenantId()));
+        newObj.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+
+
+        JSONObject custosExt = new JSONObject();
+        custosExt.put(Constants.CUSTOS_EXTENSION, newObj);
+
+
+
+        // create charon-SCIM user endpoint and hand-over the request.
+        GroupResourceManager groupResourceManager = new GroupResourceManager();
+
+
+        SCIMResponse response = groupResourceManager.updateWithPUT(custosExt.toString(), object.toString(), resourceManager,
+                attribute, excludedAttributes);
+
+
+        return buildResponse(response);
+    }
+
+    @ApiOperation(
+            value = "Return groups according to the filter, sort and pagination parameters",
+            notes = "Returns HTTP 404 if the groups are not found.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "Valid groups are found"),
+            @ApiResponse(code = 404, message = "Valid groups are not found")})
+
+    @PostMapping(value = ("/.search"), produces = {"application/json", "application/scim+json"}, consumes = {"application/scim+json"})
+    public ResponseEntity getGroupsByPost(String resourceString, @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        authHandler.validateAndConfigure(authorizationHeader, false);
+
+        GroupResourceManager groupResourceManager = new GroupResourceManager();
+
+        SCIMResponse response = groupResourceManager.listWithPOST(resourceString, resourceManager);
+
+        return buildResponse(response);
+    }
+
+    @ApiOperation(
+            value = "Return groups according to the filter, sort and pagination parameters",
+            notes = "Returns HTTP 404 if the groups are not found.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "Valid groups are found"),
+            @ApiResponse(code = 404, message = "Valid groups are not found")})
+
+    @GetMapping(produces = {"application/json", "application/scim+json"})
+    public ResponseEntity getGroup(@ApiParam(value = Constants.ATTRIBUTES_DESC, required = false)
+                                   @RequestParam(value = Constants.ATTRIBUTES, required = false) String attribute,
+                                   @ApiParam(value = Constants.EXCLUDED_ATTRIBUTES_DESC, required = false)
+                                   @RequestParam(value = Constants.EXCLUDE_ATTRIBUTES, required = false) String excludedAttributes,
+                                   @ApiParam(value = Constants.FILTER_DESC, required = false)
+                                   @RequestParam(value = Constants.FILTER, required = false) String filter,
+                                   @ApiParam(value = Constants.START_INDEX_DESC, required = false)
+                                   @RequestParam(value = Constants.START_INDEX, required = false) int startIndex,
+                                   @ApiParam(value = Constants.COUNT_DESC, required = false)
+                                   @RequestParam(value = Constants.COUNT, required = false) int count,
+                                   @ApiParam(value = Constants.SORT_BY_DESC, required = false)
+                                   @RequestParam(value = Constants.SORT_BY, required = false) String sortBy,
+                                   @ApiParam(value = Constants.SORT_ORDER_DESC, required = false)
+                                   @RequestParam(value = Constants.SORT_ORDER, required = false) String sortOrder,
+                                   @ApiParam(value = Constants.DOMAIN_DESC, required = false)
+                                   @RequestParam(value = Constants.DOMAIN, required = false) String domainName,
+                                   @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        authHandler.validateAndConfigure(authorizationHeader, false);
+
+        GroupResourceManager groupResourceManager = new GroupResourceManager();
+
+        SCIMResponse response = groupResourceManager.listWithGET(resourceManager,
+                filter, startIndex, count, sortBy, sortOrder, domainName, attribute, excludedAttributes);
+
+        return buildResponse(response);
+
+    }
+
+}
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/ServiceProviderResource.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/ServiceProviderResource.java
new file mode 100644
index 0000000..fe5a270
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/ServiceProviderResource.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim.resource;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.apache.custos.scim.resource.manager.ResourceManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.wso2.charon3.core.protocol.SCIMResponse;
+import org.wso2.charon3.core.protocol.endpoints.ServiceProviderConfigResourceManager;
+
+@RestController
+@RequestMapping(value = {"/v2/ServiceProviderConfig"})
+@Api(value = "Schema Resource Management")
+public class ServiceProviderResource extends AbstractResource {
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(UserResource.class);
+
+
+    @Autowired
+    private ResourceManager resourceManager;
+
+
+    @ApiOperation(
+            value = "Return the Service Provider Config",
+            notes = "Returns HTTP 200 if the Service Provider Config is found.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "Service Provider Config is found"),
+            @ApiResponse(code = 404, message = "Service Provider Config is not found")})
+
+    @GetMapping(produces = {"application/json", "application/scim+json"})
+    public ResponseEntity getServiceProviderConfig() {
+
+
+        ServiceProviderConfigResourceManager ServiceProviderConfigResourceManager = new ServiceProviderConfigResourceManager();
+
+        SCIMResponse response = ServiceProviderConfigResourceManager.get(null, resourceManager, null, null);
+
+        return buildResponse(response);
+
+    }
+
+}
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/UserResource.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/UserResource.java
new file mode 100644
index 0000000..728a4c3
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/UserResource.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim.resource;
+
+import io.swagger.annotations.*;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.scim.resource.manager.ResourceManager;
+import org.apache.custos.scim.utils.AuthHandler;
+import org.apache.custos.scim.utils.Constants;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.wso2.charon3.core.protocol.SCIMResponse;
+import org.wso2.charon3.core.protocol.endpoints.UserResourceManager;
+
+import java.util.Map;
+
+
+@RestController
+@RequestMapping(value = {"/v2/Users"})
+@Api(value = "User Resource Management")
+public class UserResource extends AbstractResource {
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(UserResource.class);
+
+
+    @Autowired
+    private ResourceManager resourceManager;
+
+    @Autowired
+    private AuthHandler authHandler;
+
+
+    @ApiOperation(
+            value = "Return the user with the given id",
+            notes = "Returns HTTP 200 if the user is found.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "Valid user is found"),
+            @ApiResponse(code = 404, message = "Valid user is not found")})
+
+    @GetMapping(value = {"/{id}"}, produces = {"application/json", "application/scim+json"})
+    public ResponseEntity getUser(@ApiParam(value = Constants.ID_DESC, required = true)
+                                  @PathVariable(Constants.ID) String id,
+                                  @ApiParam(value = Constants.ATTRIBUTES_DESC, required = false)
+                                  @RequestParam(value = Constants.ATTRIBUTES, required = false) String attribute,
+                                  @ApiParam(value = Constants.EXCLUDED_ATTRIBUTES_DESC, required = false)
+                                  @RequestParam(value = Constants.EXCLUDE_ATTRIBUTES, required = false) String excludedAttributes,
+                                  @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        AuthClaim claim = authHandler.validateAndConfigure(authorizationHeader, false);
+
+        JSONObject newObj = new JSONObject();
+
+        newObj.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        newObj.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        newObj.put(Constants.ID, id);
+        newObj.put(Constants.TENANT_ID, String.valueOf(claim.getTenantId()));
+        newObj.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+
+
+        JSONObject custosExtention = new JSONObject();
+        custosExtention.put(Constants.CUSTOS_EXTENSION, newObj);
+
+        // create charon-SCIM user endpoint and hand-over the request.
+        UserResourceManager userResourceManager = new UserResourceManager();
+        LOGGER.info("Id Before  " + custosExtention.toString());
+        SCIMResponse response = userResourceManager.get(custosExtention.toString(), resourceManager, attribute, excludedAttributes);
+
+        return buildResponse(response);
+    }
+
+
+    @ApiOperation(
+            value = "Return the user which was created",
+            notes = "Returns HTTP 201 if the user is successfully created.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 201, message = "Valid user is created"),
+            @ApiResponse(code = 404, message = "User is not found")})
+
+    @PostMapping(produces = {"application/json", "application/scim+json"}, consumes = {"application/scim+json"})
+    public ResponseEntity createUser(@ApiParam(value = Constants.ATTRIBUTES_DESC, required = false)
+                                     @RequestParam(value = Constants.ATTRIBUTES, required = false) String attribute,
+                                     @ApiParam(value = Constants.EXCLUDED_ATTRIBUTES_DESC, required = false)
+                                     @RequestParam(value = Constants.EXCLUDE_ATTRIBUTES, required = false) String excludedAttributes,
+                                     @RequestBody Map<String, Object> payload,
+                                     @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        AuthClaim claim = authHandler.validateAndConfigure(authorizationHeader, false);
+
+        JSONObject object = new JSONObject(payload);
+
+        JSONObject custosExtension = new JSONObject();
+
+        custosExtension.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        custosExtension.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        custosExtension.put(Constants.TENANT_ID, claim.getTenantId());
+        custosExtension.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+
+        object.put(Constants.CUSTOS_EXTENSION, custosExtension);
+
+        // create charon-SCIM user endpoint and hand-over the request.
+        UserResourceManager userResourceManager = new UserResourceManager();
+
+        LOGGER.info(object.toString());
+
+        SCIMResponse response = userResourceManager.create(object.toString(), resourceManager,
+                attribute, excludedAttributes);
+
+
+        return buildResponse(response);
+    }
+
+    @ApiOperation(
+            value = "Delete the user with the given id",
+            notes = "Returns HTTP 204 if the user is successfully deleted.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 204, message = "User is deleted"),
+            @ApiResponse(code = 404, message = "Valid user is not found")})
+
+    @DeleteMapping(path = {"/{id}"}, produces = {"application/json", "application/scim+json"})
+    public ResponseEntity deleteUser(@ApiParam(value = Constants.ID_DESC, required = true)
+                                     @PathVariable(Constants.ID) String id,
+                                     @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        AuthClaim claim = authHandler.validateAndConfigure(authorizationHeader, false);
+
+
+        JSONObject newObj = new JSONObject();
+
+
+        newObj.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        newObj.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        newObj.put(Constants.ID, id);
+        newObj.put(Constants.TENANT_ID, String.valueOf(claim.getTenantId()));
+        newObj.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+
+        JSONObject custosExtention = new JSONObject();
+        custosExtention.put(Constants.CUSTOS_EXTENSION, newObj);
+
+        // create charon-SCIM user endpoint and hand-over the request.
+        UserResourceManager userResourceManager = new UserResourceManager();
+        LOGGER.info("Id Before  " + custosExtention.toString());
+        SCIMResponse response = userResourceManager.delete(custosExtention.toString(), resourceManager);
+
+        return buildResponse(response);
+
+    }
+
+
+    @ApiOperation(
+            value = "Return users according to the filter, sort and pagination parameters",
+            notes = "Returns HTTP 404 if the users are not found.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "Valid users are found"),
+            @ApiResponse(code = 404, message = "Valid users are not found")})
+
+    @GetMapping(produces = {"application/json", "application/scim+json"})
+    public ResponseEntity getUser(@ApiParam(value = Constants.ATTRIBUTES_DESC, required = false)
+                                  @RequestParam(Constants.ATTRIBUTES) String attribute,
+                                  @ApiParam(value = Constants.EXCLUDED_ATTRIBUTES_DESC, required = false)
+                                  @RequestParam(value = Constants.EXCLUDE_ATTRIBUTES, required = false) String excludedAttributes,
+                                  @ApiParam(value = Constants.FILTER_DESC, required = false)
+                                  @RequestParam(value = Constants.FILTER, required = false) String filter,
+                                  @ApiParam(value = Constants.START_INDEX_DESC, required = false)
+                                  @RequestParam(value =Constants.START_INDEX, required = false) int startIndex,
+                                  @ApiParam(value = Constants.COUNT_DESC, required = false)
+                                  @RequestParam(value= Constants.COUNT, required = false) int count,
+                                  @ApiParam(value = Constants.SORT_BY_DESC, required = false)
+                                  @RequestParam(value =Constants.SORT_BY, required = false) String sortBy,
+                                  @ApiParam(value = Constants.SORT_ORDER_DESC, required = false)
+                                  @RequestParam(value = Constants.SORT_ORDER, required = false) String sortOrder,
+                                  @ApiParam(value = Constants.DOMAIN_DESC, required = false)
+                                  @RequestParam(value= Constants.DOMAIN, required = false) String domainName,
+                                  @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+        authHandler.validateAndConfigure(authorizationHeader, false);
+
+        UserResourceManager userResourceManager = new UserResourceManager();
+
+        SCIMResponse response = userResourceManager.listWithGET(resourceManager,
+                filter, startIndex, count, sortBy, sortOrder, domainName, attribute, excludedAttributes);
+
+        return buildResponse(response);
+
+    }
+
+
+    @ApiOperation(
+            value = "Return users according to the filter, sort and pagination parameters",
+            notes = "Returns HTTP 404 if the users are not found.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "Valid users are found"),
+            @ApiResponse(code = 404, message = "Valid users are not found")})
+
+    @PostMapping(value = {"/.search"}, produces = {"application/json", "application/scim+json"}, consumes = {"application/scim+json"})
+    public ResponseEntity getUsersByPost(String resourceString, @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        authHandler.validateAndConfigure(authorizationHeader, false);
+
+        UserResourceManager userResourceManager = new UserResourceManager();
+
+        SCIMResponse response = userResourceManager.listWithPOST(resourceString, resourceManager);
+
+        return buildResponse(response);
+
+    }
+
+
+    @ApiOperation(
+            value = "Return the updated user",
+            notes = "Returns HTTP 404 if the user is not found.")
+
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "User is updated"),
+            @ApiResponse(code = 404, message = "Valid user is not found")})
+
+    @PutMapping(path = "/{id}", produces = {"application/json", "application/scim+json"}, consumes = {"application/scim+json"})
+    public ResponseEntity updateUser(@ApiParam(value = Constants.ID_DESC, required = true)
+                                     @PathVariable(Constants.ID) String id,
+                                     @ApiParam(value = Constants.ATTRIBUTES_DESC, required = false)
+                                     @RequestParam(value = Constants.ATTRIBUTES, required = false) String attribute,
+                                     @ApiParam(value = Constants.EXCLUDED_ATTRIBUTES_DESC, required = false)
+                                     @RequestParam(value =Constants.EXCLUDE_ATTRIBUTES, required = false) String excludedAttributes,
+                                     @RequestBody Map<String, Object> payload,
+                                     @RequestHeader(value = Constants.AUTHORIZATION) String authorizationHeader) {
+
+        AuthClaim claim = authHandler.validateAndConfigure(authorizationHeader, false);
+
+        JSONObject object = new JSONObject(payload);
+
+        JSONObject custosExtension = new JSONObject();
+
+        custosExtension.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        custosExtension.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        custosExtension.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+        custosExtension.put(Constants.TENANT_ID, claim.getTenantId());
+        object.put(Constants.CUSTOS_EXTENSION, custosExtension);
+
+
+
+        JSONObject newObj = new JSONObject();
+
+        newObj.put(Constants.CLIENT_ID, claim.getIamAuthId());
+        newObj.put(Constants.CLIENT_SEC, claim.getIamAuthSecret());
+        newObj.put(Constants.ID, id);
+        newObj.put(Constants.TENANT_ID, String.valueOf(claim.getTenantId()));
+        newObj.put(Constants.ACCESS_TOKEN, authHandler.getToken(authorizationHeader));
+
+
+        JSONObject custosExt = new JSONObject();
+        custosExt.put(Constants.CUSTOS_EXTENSION, newObj);
+
+
+        // create charon-SCIM user endpoint and hand-over the request.
+        UserResourceManager userResourceManager = new UserResourceManager();
+
+
+        SCIMResponse response = userResourceManager.updateWithPUT(custosExt.toString(), object.toString(), resourceManager,
+                attribute, excludedAttributes);
+
+
+        return buildResponse(response);
+    }
+
+
+}
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/manager/ResourceManager.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/manager/ResourceManager.java
new file mode 100644
index 0000000..b03e183
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/resource/manager/ResourceManager.java
@@ -0,0 +1,812 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim.resource.manager;
+
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.iam.admin.client.IamAdminServiceClient;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.identity.service.GetUserManagementSATokenRequest;
+import org.apache.custos.scim.utils.Constants;
+import org.apache.custos.user.profile.client.UserProfileClient;
+import org.apache.custos.user.profile.service.UserProfile;
+import org.apache.custos.user.profile.service.UserStatus;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.wso2.charon3.core.attributes.Attribute;
+import org.wso2.charon3.core.attributes.SimpleAttribute;
+import org.wso2.charon3.core.config.SCIMUserSchemaExtensionBuilder;
+import org.wso2.charon3.core.encoder.JSONDecoder;
+import org.wso2.charon3.core.encoder.JSONEncoder;
+import org.wso2.charon3.core.exceptions.*;
+import org.wso2.charon3.core.extensions.UserManager;
+import org.wso2.charon3.core.objects.Group;
+import org.wso2.charon3.core.objects.User;
+import org.wso2.charon3.core.protocol.endpoints.AbstractResourceManager;
+import org.wso2.charon3.core.schema.SCIMConstants;
+import org.wso2.charon3.core.schema.SCIMResourceSchemaManager;
+import org.wso2.charon3.core.schema.SCIMResourceTypeSchema;
+import org.wso2.charon3.core.utils.codeutils.SearchRequest;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.wso2.charon3.core.protocol.endpoints.AbstractResourceManager.getDecoder;
+import static org.wso2.charon3.core.protocol.endpoints.AbstractResourceManager.getEncoder;
+
+/**
+ * Class responsible for manage Users. Responsible for request response formatting and
+ * interact with core services
+ */
+@Component
+public class ResourceManager implements UserManager {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ResourceManager.class);
+
+
+    @Autowired
+    private UserProfileClient userProfileClient;
+
+    @Autowired
+    private IamAdminServiceClient iamAdminServiceClient;
+
+    @Autowired
+    private IdentityClient identityClient;
+
+    @Autowired
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+
+    public ResourceManager(@Value("${scim.resource.user.endpoint}") String userEndpoint,
+                           @Value("${scim.resource.group.endpoint}") String groupEndpoint) {
+
+        Map<String, String> endpointMap = new HashMap();
+        endpointMap.put(SCIMConstants.USER_ENDPOINT, userEndpoint);
+        endpointMap.put(SCIMConstants.GROUP_ENDPOINT, groupEndpoint);
+        AbstractResourceManager.setEndpointURLMap(endpointMap);
+
+        try {
+            SCIMUserSchemaExtensionBuilder.getInstance()
+                    .buildUserSchemaExtension(Constants.USER_SCHEMA_EXTENTION_LOCATION);
+        } catch (Exception e) {
+            String msg = "User schema building error";
+            LOGGER.error(msg, e);
+            throw new RuntimeException(msg, e);
+        }
+    }
+
+
+    @Override
+    public User createUser(User user, Map<String, Boolean> map) throws CharonException, ConflictException, BadRequestException {
+        Attribute attribute = user.getAttribute(Constants.CUSTOS_EXTENSION);
+        Attribute clientId = attribute.getSubAttribute(Constants.CLIENT_ID);
+        Attribute clientSec = attribute.getSubAttribute(Constants.CLIENT_SEC);
+        Attribute tenantId = attribute.getSubAttribute(Constants.TENANT_ID);
+        String clId = ((SimpleAttribute) clientId).getStringValue();
+        String clSec = ((SimpleAttribute) clientSec).getStringValue();
+        String tenant = ((SimpleAttribute) tenantId).getStringValue();
+
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clId)
+                .setClientSecret(clSec)
+                .setTenantId(Long.valueOf(tenant))
+                .build();
+        AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+        if (token != null && token.getAccessToken() != null) {
+
+            UserRepresentation userRepresentation = UserRepresentation
+                    .newBuilder()
+                    .setFirstName(user.getName().getGivenName())
+                    .setLastName(user.getName().getFamilyName())
+                    .setEmail(user.getEmails().get(0).getValue())
+                    .setUsername(user.getExternalId())
+                    .setPassword(user.getPassword())
+                    .setTemporaryPassword(false)
+                    .build();
+
+            RegisterUserRequest registerUserRequest = RegisterUserRequest.newBuilder()
+                    .setTenantId(Long.valueOf(tenant))
+                    .setAccessToken(token.getAccessToken())
+                    .setUser(userRepresentation)
+                    .build();
+
+            RegisterUserResponse registerUserResponse = iamAdminServiceClient.registerUser(registerUserRequest);
+
+            if (registerUserResponse.getIsRegistered()) {
+
+                if (user.getActive()) {
+
+                    UserSearchMetadata metada = UserSearchMetadata.newBuilder().setUsername(user.getExternalId()).build();
+
+                    UserSearchRequest request = UserSearchRequest
+                            .newBuilder()
+                            .setTenantId(Long.valueOf(tenant))
+                            .setAccessToken(token.getAccessToken())
+                            .setUser(metada)
+                            .build();
+
+
+                    userRepresentation = iamAdminServiceClient.enableUser(request);
+
+                    if (userRepresentation != null) {
+
+                        UserProfile profile = this.convertToProfile(userRepresentation);
+
+                        org.apache.custos.user.profile.service.UserProfileRequest profileRequest =
+                                org.apache.custos.user.profile.service.UserProfileRequest.newBuilder()
+                                        .setProfile(profile)
+                                        .setTenantId(request.getTenantId())
+                                        .build();
+
+                        userProfileClient.createUserProfile(profileRequest);
+                    }
+                }
+
+                try {
+                    return this.convert(userRepresentation);
+                } catch (InternalErrorException e) {
+                    String msg = "Error occurred while converting user representation to charon";
+                    throw new CharonException(msg, e);
+                }
+
+            } else {
+                String msg = "User not successfully registered";
+                LOGGER.error(msg);
+                throw new RuntimeException(msg);
+            }
+
+        } else {
+            String msg = "Token not found ";
+            LOGGER.error(msg);
+            throw new RuntimeException(msg);
+        }
+
+    }
+
+
+    @Override
+    public User getUser(String id, Map<String, Boolean> map) throws CharonException, BadRequestException, NotFoundException {
+        JSONObject object = new JSONObject(id);
+        Object obj = object.get(Constants.CUSTOS_EXTENSION);
+        String clientId = ((String) ((JSONObject) obj).get(Constants.CLIENT_ID));
+        String clientSec = ((String) ((JSONObject) obj).get(Constants.CLIENT_SEC));
+        String decodedId = ((String) ((JSONObject) obj).get(Constants.ID));
+        String tenantId = ((String) ((JSONObject) obj).get(Constants.TENANT_ID));
+
+        long tenant = Long.valueOf(tenantId);
+
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setClientSecret(clientSec)
+                .setTenantId(tenant)
+                .build();
+        AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+        if (token != null && token.getAccessToken() != null) {
+
+            UserSearchMetadata metada = UserSearchMetadata.newBuilder().setUsername(decodedId).build();
+
+            UserSearchRequest request = UserSearchRequest
+                    .newBuilder()
+                    .setTenantId(tenant)
+                    .setAccessToken(token.getAccessToken())
+                    .setUser(metada)
+                    .build();
+
+            UserRepresentation userRep = iamAdminServiceClient.getUser(request);
+
+            if (userRep == null || userRep.getUsername().equals("")) {
+                throw new NotFoundException("User not found");
+            }
+
+            try {
+                return convert(userRep);
+            } catch (InternalErrorException e) {
+                throw new CharonException(SCIMConstants.USER);
+            }
+
+        } else {
+            String msg = "Token not found ";
+            LOGGER.error(msg);
+            throw new NotFoundException(msg);
+        }
+    }
+
+    @Override
+    public void deleteUser(String id) throws NotFoundException, CharonException, NotImplementedException, BadRequestException {
+        JSONObject object = new JSONObject(id);
+        Object obj = object.get(Constants.CUSTOS_EXTENSION);
+        String clientId = ((String) ((JSONObject) obj).get(Constants.CLIENT_ID));
+        String clientSec = ((String) ((JSONObject) obj).get(Constants.CLIENT_SEC));
+        String decodedId = ((String) ((JSONObject) obj).get(Constants.ID));
+        String tenantId = ((String) ((JSONObject) obj).get(Constants.TENANT_ID));
+
+        long tenant = Long.valueOf(tenantId);
+
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setClientSecret(clientSec)
+                .setTenantId(tenant)
+                .build();
+        AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+        if (token != null && token.getAccessToken() != null) {
+
+            UserProfile profileReq = UserProfile.newBuilder().setUsername(decodedId).build();
+
+            org.apache.custos.user.profile.service.UserProfileRequest req =
+                    org.apache.custos.user.profile.service.UserProfileRequest
+                            .newBuilder()
+                            .setTenantId(tenant)
+                            .setProfile(profileReq)
+                            .build();
+
+            UserProfile profile = userProfileClient.getUser(req);
+            UserSearchMetadata metada = UserSearchMetadata.newBuilder().setUsername(decodedId).build();
+
+            UserSearchRequest request = UserSearchRequest
+                    .newBuilder()
+                    .setTenantId(tenant)
+                    .setAccessToken(token.getAccessToken())
+                    .setUser(metada)
+                    .build();
+
+            if (profile != null && !profile.getUsername().trim().equals("")) {
+
+
+                UserProfile deletedProfile = userProfileClient.deleteUser(req);
+
+                if (deletedProfile != null) {
+                    iamAdminServiceClient.deleteUser(request);
+                } else {
+                    String msg = "User profile deletion failed for " + decodedId;
+                    LOGGER.error(msg);
+                    throw new CharonException(msg);
+                }
+
+            } else {
+                iamAdminServiceClient.deleteUser(request);
+
+            }
+        }
+    }
+
+    @Override
+    public List<Object> listUsersWithPost(SearchRequest searchRequest, Map<String, Boolean> map) throws CharonException, NotImplementedException, BadRequestException {
+        throw new NotImplementedException("Method not implemented");
+    }
+
+    @Override
+    public User updateUser(User user, Map<String, Boolean> map) throws NotImplementedException, CharonException, BadRequestException, NotFoundException {
+        Attribute attribute = user.getAttribute(Constants.CUSTOS_EXTENSION);
+        Attribute clientId = attribute.getSubAttribute(Constants.CLIENT_ID);
+        Attribute clientSec = attribute.getSubAttribute(Constants.CLIENT_SEC);
+        Attribute tenantId = attribute.getSubAttribute(Constants.TENANT_ID);
+        String clId = ((SimpleAttribute) clientId).getStringValue();
+        String clSec = ((SimpleAttribute) clientSec).getStringValue();
+        String tenant = ((SimpleAttribute) tenantId).getStringValue();
+
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clId)
+                .setClientSecret(clSec)
+                .setTenantId(Long.valueOf(tenant))
+                .build();
+        AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+        if (token != null && token.getAccessToken() != null) {
+
+            UserRepresentation userRepresentation = UserRepresentation
+                    .newBuilder()
+                    .setFirstName(user.getName().getGivenName())
+                    .setLastName(user.getName().getFamilyName())
+                    .setEmail(user.getEmails().get(0).getValue())
+                    .setUsername(user.getUsername())
+                    .build();
+
+            UpdateUserProfileRequest registerUserRequest = UpdateUserProfileRequest.newBuilder()
+                    .setTenantId(Long.valueOf(tenant))
+                    .setAccessToken(token.getAccessToken())
+                    .setUser(userRepresentation)
+                    .build();
+
+            OperationStatus status = iamAdminServiceClient.updateUserProfile(registerUserRequest);
+
+            if (status.getStatus()) {
+                UserSearchMetadata metada = UserSearchMetadata.newBuilder().setUsername(user.getUsername()).build();
+
+                UserSearchRequest request = UserSearchRequest
+                        .newBuilder()
+                        .setTenantId(Long.valueOf(tenant))
+                        .setAccessToken(token.getAccessToken())
+                        .setUser(metada)
+                        .build();
+                UserRepresentation enabledUser = null;
+                if (user.getActive()) {
+                    enabledUser = iamAdminServiceClient.enableUser(request);
+                } else {
+                    enabledUser = iamAdminServiceClient.disableUser(request);
+                }
+                if (enabledUser != null) {
+
+                    UserProfile profile = this.convertToProfile(enabledUser);
+
+                    org.apache.custos.user.profile.service.UserProfileRequest profileRequest =
+                            org.apache.custos.user.profile.service.UserProfileRequest.newBuilder()
+                                    .setProfile(profile)
+                                    .setTenantId(request.getTenantId())
+                                    .build();
+
+                    UserProfile exProfile = userProfileClient.getUser(profileRequest);
+
+                    if (exProfile.getUsername().equals("")) {
+                        userProfileClient.createUserProfile(profileRequest);
+                    } else {
+                        userProfileClient.updateUserProfile(profileRequest);
+                    }
+                }
+
+                try {
+                    return this.convert(enabledUser);
+                } catch (InternalErrorException e) {
+                    String msg = "Error occurred while converting user representation to charon";
+                    throw new CharonException(msg, e);
+                }
+
+            } else {
+                String msg = "User not successfully registered";
+                LOGGER.error(msg);
+                throw new RuntimeException(msg);
+            }
+
+        } else {
+            String msg = "Token not found ";
+            LOGGER.error(msg);
+            throw new RuntimeException(msg);
+        }
+    }
+
+
+    @Override
+    public Group createGroup(Group group, Map<String, Boolean> map) throws CharonException, ConflictException, NotImplementedException, BadRequestException {
+
+        List<Object> members = group.getMembers();
+
+        String str = (String) members.get(0);
+
+        JSONObject obj = new JSONObject(str);
+
+        String clientId = ((String) ((JSONObject) obj).get(Constants.CLIENT_ID));
+        String clientSec = ((String) ((JSONObject) obj).get(Constants.CLIENT_SEC));
+        String tenantId = ((String) ((JSONObject) obj).get(Constants.TENANT_ID));
+
+        long tenant = Long.valueOf(tenantId);
+
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setClientSecret(clientSec)
+                .setTenantId(tenant)
+                .build();
+
+        AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+        if (token != null && token.getAccessToken() != null) {
+
+            GroupRepresentation representation = GroupRepresentation
+                    .newBuilder()
+                    .setName(group.getDisplayName())
+                    .build();
+
+            GroupsRequest request = GroupsRequest
+                    .newBuilder()
+                    .setAccessToken(token.getAccessToken())
+                    .setTenantId(tenant)
+                    .setClientId(clientId)
+                    .addGroups(representation)
+                    .build();
+
+            GroupsResponse response = iamAdminServiceClient.createGroups(request);
+
+            org.apache.custos.user.profile.service.Group groupR =
+                    org.apache.custos.user.profile.service.Group
+                            .newBuilder()
+                            .setId(response.getGroups(0).getId())
+                            .setName(group.getDisplayName())
+                            .build();
+
+            org.apache.custos.user.profile.service.GroupRequest groupRequest =
+                    org.apache.custos.user.profile.service.GroupRequest
+                            .newBuilder()
+                            .setTenantId(tenant)
+                            .setGroup(groupR)
+                            .build();
+            userProfileClient.createGroup(groupRequest);
+
+            try {
+                return convert(response.getGroups(0));
+            } catch (InternalErrorException e) {
+                String msg = "Error occurred while converting group representation to charon";
+                throw new CharonException(msg, e);
+            }
+
+        } else {
+            String msg = "Token not found ";
+            LOGGER.error(msg);
+            throw new RuntimeException(msg);
+        }
+
+    }
+
+    @Override
+    public Group getGroup(String id, Map<String, Boolean> map) throws NotImplementedException, BadRequestException, CharonException, NotFoundException {
+        JSONObject object = new JSONObject(id);
+        Object obj = object.get(Constants.CUSTOS_EXTENSION);
+        String clientId = ((String) ((JSONObject) obj).get(Constants.CLIENT_ID));
+        String clientSec = ((String) ((JSONObject) obj).get(Constants.CLIENT_SEC));
+        String decodedId = ((String) ((JSONObject) obj).get(Constants.ID));
+        String tenantId = ((String) ((JSONObject) obj).get(Constants.TENANT_ID));
+        String accessToken = ((String) ((JSONObject) obj).get(Constants.ACCESS_TOKEN));
+
+        long tenant = Long.valueOf(tenantId);
+
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setClientSecret(clientSec)
+                .setTenantId(tenant)
+                .build();
+        AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+        if (token != null && token.getAccessToken() != null) {
+
+            GroupRepresentation groupRepresentation = GroupRepresentation.newBuilder().setId(decodedId).build();
+
+            GroupRequest groupsRequest = GroupRequest
+                    .newBuilder()
+                    .setAccessToken(token.getAccessToken())
+                    .setClientId(clientId)
+                    .setClientSec(clientSec)
+                    .setTenantId(tenant)
+                    .setGroup(groupRepresentation)
+                    .build();
+
+            GroupRepresentation representation = iamAdminServiceClient.findGroup(groupsRequest);
+
+            try {
+                return convert(representation);
+            } catch (InternalErrorException e) {
+                throw new CharonException(SCIMConstants.GROUP);
+            }
+
+        } else {
+            String msg = "Token not found ";
+            LOGGER.error(msg);
+            throw new RuntimeException(msg);
+        }
+
+    }
+
+    @Override
+    public void deleteGroup(String id) throws NotFoundException, CharonException, NotImplementedException, BadRequestException {
+        JSONObject object = new JSONObject(id);
+        Object obj = object.get(Constants.CUSTOS_EXTENSION);
+        String clientId = ((String) ((JSONObject) obj).get(Constants.CLIENT_ID));
+        String clientSec = ((String) ((JSONObject) obj).get(Constants.CLIENT_SEC));
+        String decodedId = ((String) ((JSONObject) obj).get(Constants.ID));
+        String tenantId = ((String) ((JSONObject) obj).get(Constants.TENANT_ID));
+        String accessToken = ((String) ((JSONObject) obj).get(Constants.ACCESS_TOKEN));
+
+        long tenant = Long.valueOf(tenantId);
+
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setClientSecret(clientSec)
+                .setTenantId(tenant)
+                .build();
+        AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+        if (token != null && token.getAccessToken() != null) {
+
+            GroupRepresentation groupRepresentation = GroupRepresentation.newBuilder().setId(decodedId).build();
+
+            GroupRequest groupsRequest = GroupRequest
+                    .newBuilder()
+                    .setAccessToken(token.getAccessToken())
+                    .setClientId(clientId)
+                    .setClientSec(clientSec)
+                    .setTenantId(tenant)
+                    .setGroup(groupRepresentation)
+                    .build();
+
+            OperationStatus response = iamAdminServiceClient.deleteGroup(groupsRequest);
+
+
+            if (response.getStatus()) {
+                org.apache.custos.user.profile.service.Group group = org.apache.custos.user.profile.service.Group.newBuilder()
+                        .setId(decodedId)
+                        .build();
+
+                org.apache.custos.user.profile.service.GroupRequest groupRequest = org.apache.custos.user.profile.service.GroupRequest
+                        .newBuilder().
+                                setTenantId(tenant).
+                                setGroup(group).build();
+
+                userProfileClient.deleteGroup(groupRequest);
+            }
+
+        } else {
+            String msg = "Token not found ";
+            LOGGER.error(msg);
+            throw new RuntimeException(msg);
+        }
+
+    }
+
+    @Override
+    public Group updateGroup(Group group, Group group1, Map<String, Boolean> map) throws NotImplementedException, BadRequestException, CharonException, NotFoundException {
+        List<Object> members = group1.getMembers();
+
+        String str = (String) members.get(0);
+
+        JSONObject obj = new JSONObject(str);
+
+        String clientId = ((String) ((JSONObject) obj).get(Constants.CLIENT_ID));
+        String clientSec = ((String) ((JSONObject) obj).get(Constants.CLIENT_SEC));
+        String tenantId = ((String) ((JSONObject) obj).get(Constants.TENANT_ID));
+
+        long tenant = Long.valueOf(tenantId);
+
+
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setClientSecret(clientSec)
+                .setTenantId(tenant)
+                .build();
+        AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+        if (token != null && token.getAccessToken() != null) {
+
+            GroupRepresentation representation = GroupRepresentation
+                    .newBuilder()
+                    .setId(group1.getId())
+                    .setName(group1.getDisplayName())
+                    .build();
+
+            GroupRequest request = GroupRequest
+                    .newBuilder()
+                    .setAccessToken(token.getAccessToken())
+                    .setTenantId(tenant)
+                    .setClientId(clientId)
+                    .setClientSec(clientSec)
+                    .setGroup(representation)
+                    .build();
+
+            GroupRepresentation response = iamAdminServiceClient.updateGroup(request);
+
+            org.apache.custos.user.profile.service.Group groupR =
+                    org.apache.custos.user.profile.service.Group
+                            .newBuilder()
+                            .setId(group1.getId())
+                            .setName(group1.getDisplayName())
+                            .build();
+
+            org.apache.custos.user.profile.service.GroupRequest groupRequest =
+                    org.apache.custos.user.profile.service.GroupRequest
+                            .newBuilder()
+                            .setTenantId(tenant)
+                            .setGroup(groupR)
+                            .build();
+            userProfileClient.updateGroup(groupRequest);
+
+            try {
+                return convert(response);
+            } catch (InternalErrorException e) {
+                String msg = "Error occurred while converting group representation to charon";
+                throw new CharonException(msg, e);
+            }
+
+        } else {
+            String msg = "Token not found ";
+            LOGGER.error(msg);
+            throw new RuntimeException(msg);
+        }
+
+    }
+
+    @Override
+    public List<Object> listGroupsWithPost(SearchRequest searchRequest, Map<String, Boolean> map) throws NotImplementedException, BadRequestException, CharonException {
+        throw new BadRequestException("Method not implemented");
+    }
+
+
+    @Override
+    public User getMe(String s, Map<String, Boolean> map) throws CharonException, BadRequestException, NotFoundException {
+        throw new BadRequestException("Method not implemented");
+    }
+
+    @Override
+    public User createMe(User user, Map<String, Boolean> map) throws CharonException, ConflictException, BadRequestException {
+        throw new BadRequestException("Method not implemented");
+    }
+
+    @Override
+    public void deleteMe(String s) throws NotFoundException, CharonException, NotImplementedException, BadRequestException {
+        throw new NotImplementedException("Method not implemented");
+    }
+
+    @Override
+    public User updateMe(User user, Map<String, Boolean> map) throws NotImplementedException, CharonException, BadRequestException, NotFoundException {
+        throw new NotImplementedException("Method not implemented");
+    }
+
+
+    private User convert(UserRepresentation representation) throws BadRequestException, CharonException, InternalErrorException {
+
+        //obtain the json encoder
+        JSONEncoder encoder = getEncoder();
+
+        //obtain the json decoder
+        JSONDecoder decoder = getDecoder();
+
+        //obtain the schema corresponding to user
+        // unless configured returns core-user schema or else returns extended user schema)
+        SCIMResourceTypeSchema schema = SCIMResourceSchemaManager.getInstance().getUserResourceSchema();
+
+        String scimObjectString = getUser(representation);
+
+        //decode the SCIM User object, encoded in the submitted payload.
+        User user = (User) decoder.decodeResource(scimObjectString, schema, new User());
+        return user;
+
+    }
+
+
+    private Group convert(GroupRepresentation representation) throws BadRequestException, CharonException, InternalErrorException {
+
+        //obtain the json encoder
+        JSONEncoder encoder = getEncoder();
+
+        //obtain the json decoder
+        JSONDecoder decoder = getDecoder();
+
+        //obtain the schema corresponding to user
+        // unless configured returns core-user schema or else returns extended user schema)
+        SCIMResourceTypeSchema schema = SCIMResourceSchemaManager.getInstance().getGroupResourceSchema();
+
+        String scimObjectString = getGroup(representation);
+
+        //decode the SCIM User object, encoded in the submitted payload.
+        Group user = (Group) decoder.decodeResource(scimObjectString, schema, new Group());
+        return user;
+
+    }
+
+
+    private String getUser(UserRepresentation representation) {
+        JSONObject object = new JSONObject();
+        object.put("id", representation.getUsername());
+        object.put("externalId", representation.getUsername());
+        object.put("userName", representation.getUsername());
+        boolean active = representation.getState().equals("ACTIVE") ? true : false;
+        object.put("active", active);
+        JSONObject name = new JSONObject();
+        name.put("familyName", representation.getLastName());
+        name.put("givenName", representation.getFirstName());
+        object.put("name", name);
+        Instant instant = Instant.ofEpochMilli(Double.doubleToLongBits(representation.getCreationTime()));
+        JSONObject meta = new JSONObject();
+        meta.put("created", instant.toString());
+        String location = "https://custos.scigap.org:32036/scim/v2/Users/" + representation.getUsername();
+        meta.put("location", location);
+        meta.put("resourceType", SCIMConstants.USER);
+
+        object.put("meta", meta);
+        JSONArray array = new JSONArray();
+        array.put(SCIMConstants.CORE_SCHEMA_URI);
+        object.put("schemas", array);
+
+
+        JSONArray emails = new JSONArray();
+        emails.put(representation.getEmail());
+        object.put("emails", emails);
+        return object.toString();
+
+    }
+
+    private UserProfile convertToProfile(UserRepresentation representation) {
+        UserProfile.Builder profileBuilder = UserProfile.newBuilder();
+
+
+        if (representation.getRealmRolesCount() > 0) {
+            profileBuilder.addAllRealmRoles(representation.getRealmRolesList());
+
+        }
+
+        if (representation.getClientRolesCount() > 0) {
+            profileBuilder.addAllClientRoles(representation.getClientRolesList());
+
+        }
+
+        if (representation.getAttributesCount() > 0) {
+            List<UserAttribute> attributeList = representation.getAttributesList();
+
+            List<org.apache.custos.user.profile.service.UserAttribute> userAtrList = new ArrayList<>();
+            attributeList.forEach(atr -> {
+                org.apache.custos.user.profile.service.UserAttribute userAttribute =
+                        org.apache.custos.user.profile.service.UserAttribute
+                                .newBuilder()
+                                .setKey(atr.getKey())
+                                .addAllValue(atr.getValuesList())
+                                .build();
+
+                userAtrList.add(userAttribute);
+            });
+            profileBuilder.addAllAttributes(userAtrList);
+
+
+        }
+
+        profileBuilder.setUsername(representation.getUsername().toLowerCase());
+        profileBuilder.setFirstName(representation.getFirstName());
+        profileBuilder.setLastName(representation.getLastName());
+        profileBuilder.setEmail(representation.getEmail());
+        UserStatus userStatus = representation.getState().equals("ACTIVE") ? UserStatus.ACTIVE : UserStatus.SUSPENDED;
+        profileBuilder.setStatus(userStatus);
+
+        return profileBuilder.build();
+
+    }
+
+    private String getGroup(GroupRepresentation representation) {
+        JSONObject object = new JSONObject();
+        object.put("id", representation.getId());
+        object.put("displayName", representation.getName());
+        JSONObject meta = new JSONObject();
+        String location = "https://custos.scigap.org:32036/scim/v2/Groups/" + representation.getId();
+        meta.put("location", location);
+        meta.put("resourceType", SCIMConstants.USER);
+
+        object.put("meta", meta);
+        JSONArray array = new JSONArray();
+        array.put(SCIMConstants.CORE_SCHEMA_URI);
+        object.put("schemas", array);
+
+        return object.toString();
+
+    }
+
+
+}
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/utils/AuthHandler.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/utils/AuthHandler.java
new file mode 100644
index 0000000..6857901
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/utils/AuthHandler.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim.utils;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.json.JSONObject;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpStatusCodeException;
+
+import java.util.Map;
+
+@Component
+public class AuthHandler extends AuthInterceptor {
+
+
+    public AuthHandler(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+
+    public String getToken(String headerValue) {
+        String prefix = "Bearer";
+        String token = headerValue.substring(prefix.length());
+        return token.trim();
+    }
+
+    public AuthClaim validateAndConfigure(String header, boolean userTokenValidation) throws HttpStatusCodeException {
+        String token = this.getToken(header);
+        AuthClaim claim = null;
+        if (userTokenValidation) {
+            claim = authorizeUsingUserToken(token);
+        } else {
+            claim = authorize(token);
+        }
+
+        if (claim == null) {
+            throw new NotAuthorizedException();
+        }
+
+       return claim;
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String s, Metadata metadata, ReqT reqT) {
+        return null;
+    }
+}
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/utils/Constants.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/utils/Constants.java
new file mode 100644
index 0000000..a8b7131
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/utils/Constants.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim.utils;
+
+public final class Constants {
+    public static final String CONTENT_TYPE = "Content-Type";
+    public static final String ATTRIBUTES = "attributes";
+    public static final String EXCLUDE_ATTRIBUTES = "excludedAttributes";
+    public static final String FILTER = "filter";
+    public static final String START_INDEX = "startIndex";
+    public static final String COUNT = "count";
+    public static final String SORT_BY = "sortBy";
+    public static final String SORT_ORDER = "sortOder";
+    public static final String APPLICATION_SCIM_JSON = "application/scim+json";
+    public static final String APPLICATION_JSON = "application/json";
+    public static final String ACCEPT_HEADER = "Accept";
+    public static final String ID = "id";
+    public static final String DOMAIN = "domain";
+    public static final String AUTHORIZATION = "Authorization";
+
+    public static final String RESOURCE_STRING = "RESOURCE_STRING";
+    public static final String HTTP_VERB = "HTTP_VERB";
+    public static final String SEARCH = ".search";
+
+    public static final String ACCEPT_HEADER_DESC =
+            "Specify media types which are acceptable for the response.";
+    public static final String CONTENT_TYPE_HEADER_DESC =
+            "Indicates the media type of the entity-body sent to the recipient.";
+    public static final String ID_DESC = "Unique id of the resource type.";
+    public static final String ATTRIBUTES_DESC = "SCIM defined attributes parameter.";
+    public static final String EXCLUDED_ATTRIBUTES_DESC = "SCIM defined excludedAttribute parameter.";
+    public static final String FILTER_DESC = "Filter expression for filtering";
+    public static final String COUNT_DESC = "Specifies the desired maximum number of query results per page.";
+    public static final String SORT_BY_DESC = "Specifies the attribute whose value\n" +
+            "SHALL be used to order the returned responses";
+    public static final String SORT_ORDER_DESC = "The order in which the \"sortBy\" parameter is applied.";
+    public static final String START_INDEX_DESC = "The 1-based index of the first query result";
+    public static final String DOMAIN_DESC = "Domain of the provisioning user";
+
+    public static final String USER_SCHEMA_EXTENTION_LOCATION = "/home/ubuntu/schemas/custos_user_schema_extention.json";
+
+    public static final String CUSTOS_EXTENSION = "custosExtension";
+    public static final String CUSOTS_CLIENT_ROLES = "clientRoles";
+    public static final String CUSTOS_ATTRIBUTES = "attributes";
+    public static final String CUSTOS_ATTRIBUTES_KEY = "key";
+    public static final String CUSTOS_ATTRIBUTES_VALUE = "value";
+    public static final String CLIENT_ID = "clientId";
+    public static final String CLIENT_SEC = "clientSec";
+    public static final String ACCESS_TOKEN = "accessToken";
+    public static final String TENANT_ID = "tenantId";
+
+    public static final String EXTERNAL_ID = "externalId";
+
+    public static final String MEMBERS = "members";
+
+    public static final String VALUE = "value";
+
+}
diff --git a/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/utils/NotAuthorizedException.java b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/utils/NotAuthorizedException.java
new file mode 100644
index 0000000..5ced61b
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/java/org/apache/custos/scim/utils/NotAuthorizedException.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.scim.utils;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(value = HttpStatus.UNAUTHORIZED)
+public class NotAuthorizedException extends RuntimeException {
+}
diff --git a/custos-integration-services/scim-service/src/main/resources/application.properties b/custos-integration-services/scim-service/src/main/resources/application.properties
new file mode 100644
index 0000000..480f8fe
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/resources/application.properties
@@ -0,0 +1,29 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+server.port=8080
+grpc.port=7000
+spring.application.name=scimService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
+logging.level.root=INFO
+#logging.level.org.springframework.web=INFO
\ No newline at end of file
diff --git a/custos-integration-services/scim-service/src/main/resources/bootstrap.properties b/custos-integration-services/scim-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default
diff --git a/custos-integration-services/scim-service/src/main/resources/custos_user_schema_extention.bk.json b/custos-integration-services/scim-service/src/main/resources/custos_user_schema_extention.bk.json
new file mode 100644
index 0000000..5dba29f
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/resources/custos_user_schema_extention.bk.json
@@ -0,0 +1,149 @@
+[
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension.clientRoles",
+    "attributeName": "clientRoles",
+    "dataType": "string",
+    "multiValued": "true",
+    "multiValuedAttributeChildName": "null",
+    "description": "client related roles",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension.clientId",
+    "attributeName": "clientId",
+    "dataType": "string",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "client Id",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension.clientSec",
+    "attributeName": "clientSec",
+    "dataType": "string",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "client sec",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension.accessToken",
+    "attributeName": "accessToken",
+    "dataType": "string",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "access token",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension.attributes",
+    "attributeName": "attributes",
+    "dataType": "complex",
+    "multiValued": "true",
+    "multiValuedAttributeChildName": "null",
+    "description": "User attributes",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "key value",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custos.attributes.key",
+    "attributeName": "key",
+    "dataType": "string",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "Attribute key",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "true",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custos.attributes.value",
+    "attributeName": "value",
+    "dataType": "string",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "Attribute value",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "true",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension",
+    "attributeName": "custosExtension",
+    "dataType": "complex",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "Custos Extension",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "clientRoles attributes",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  }
+]
\ No newline at end of file
diff --git a/custos-integration-services/scim-service/src/main/resources/custos_user_schema_extention.json b/custos-integration-services/scim-service/src/main/resources/custos_user_schema_extention.json
new file mode 100644
index 0000000..f26971b
--- /dev/null
+++ b/custos-integration-services/scim-service/src/main/resources/custos_user_schema_extention.json
@@ -0,0 +1,91 @@
+[{
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension.clientId",
+    "attributeName": "clientId",
+    "dataType": "string",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "client Id",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension.clientSec",
+    "attributeName": "clientSec",
+    "dataType": "string",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "client sec",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension.accessToken",
+    "attributeName": "accessToken",
+    "dataType": "string",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "access token",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension.tenantId",
+    "attributeName": "tenantId",
+    "dataType": "string",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "access token",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "null",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  },
+  {
+    "attributeURI": "urn:scim:schemas:extension:custos:1.0:custosExtension",
+    "attributeName": "custosExtension",
+    "dataType": "complex",
+    "multiValued": "false",
+    "multiValuedAttributeChildName": "null",
+    "description": "Custos Extension",
+    "schemaURI": "urn:scim:schemas:extension:custos:1.0",
+    "readOnly": "false",
+    "required": "false",
+    "caseExact": "false",
+    "subAttributes": "clientId clientSec accessToken tenantId",
+    "mutability": "readWrite",
+    "returned": "default",
+    "uniqueness": "none",
+    "canonicalValues": [],
+    "referenceTypes": []
+  }
+]
\ No newline at end of file
diff --git a/custos-integration-services/sharing-management-service-parent/pom.xml b/custos-integration-services/sharing-management-service-parent/pom.xml
new file mode 100644
index 0000000..75c1b8d
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sharing-management-service-parent</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>sharing-management-service</module>
+        <module>sharing-management-service-sidecar</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/Dockerfile b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/Dockerfile
new file mode 100644
index 0000000..6dad233
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/Dockerfile
@@ -0,0 +1,3 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/sharing-management-service.pb /data/sharing-management-service.pb
+COPY src/main/resources/envoy.yaml  /etc/envoy/envoy.yaml
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/pom.xml b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/pom.xml
new file mode 100644
index 0000000..2179362
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>sharing-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sharing-management-service-sidecar</artifactId>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/envoy.yaml b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..59a2778
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/envoy.yaml
@@ -0,0 +1,48 @@
+admin:
+  access_log_path: /tmp/admin_access.log
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+  listeners:
+    - name: main-listener
+      address:
+        socket_address: { address: 0.0.0.0, port_value: 50000 }
+      filter_chains:
+        - filters:
+            - name: envoy.http_connection_manager
+              config:
+                stat_prefix: grpc_json
+                codec_type: AUTO
+                route_config:
+                  name: local_route
+                  virtual_hosts:
+                    - name: local_service
+                      domains: ["*"]
+                      routes:
+                        - match: { prefix: "/", grpc: {} }
+                          route: { cluster: grpc-backend-services, timeout: { seconds: 60 } }
+                http_filters:
+                  - name: envoy.grpc_json_transcoder
+                    config:
+                      proto_descriptor: "/data/sharing-management-service.pb"
+                      services: ["org.apache.custos.sharing.management.service.SharingManagementService"]
+                      convert_grpc_status: true
+                      print_options:
+                        add_whitespace: true
+                        always_print_primitive_fields: true
+                        always_print_enums_as_ints: false
+                        preserve_proto_field_names: true
+                  - name: envoy.router
+
+  clusters:
+    - name: grpc-backend-services
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: localhost
+            port_value: 7000
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/sharing-management-service.pb b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/sharing-management-service.pb
new file mode 100644
index 0000000..227eb2a
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/sharing-management-service.pb
Binary files differ
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/Dockerfile b/custos-integration-services/sharing-management-service-parent/sharing-management-service/Dockerfile
new file mode 100644
index 0000000..6457ff8
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/pom.xml b/custos-integration-services/sharing-management-service-parent/sharing-management-service/pom.xml
new file mode 100644
index 0000000..9015d9f
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/pom.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~  http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>sharing-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sharing-management-service</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>iam-admin-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>sharing-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>federated-authentication-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.api.grpc</groupId>
+            <artifactId>proto-google-common-protos</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/.helmignore b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/Chart.yaml b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..c79c3bf
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos sharing management service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/NOTES.txt b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/_helpers.tpl b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/deployment.yaml b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..2fe140f
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,78 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+            - name: grpc
+              containerPort: {{ .Values.service.grpcport }}
+              protocol: TCP
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+        - name: {{ .Chart.Name }}-envoy-proxy
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.proxy.repository }}:{{ .Values.proxy.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: envoyhttp
+              containerPort: {{ .Values.proxy.port }}
+              protocol: TCP
+            - name: adminhttp
+              containerPort: {{ .Values.proxy.adminport }}
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: {{ .Values.service.port }}
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress-grpc.yaml b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress-grpc.yaml
new file mode 100644
index 0000000..3fe743d
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress-grpc.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: "nginx"
+    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
+    cert-manager.io/cluster-issuer: letsencrypt-production
+  name: ${artifactId}-ingress-grpc
+spec:
+  rules:
+     - host: custos.scigap.org
+       http:
+        paths:
+          - path: /org.apache.custos.sharing.management.service.SharingManagementService(/|$)(.*)
+            backend:
+              serviceName: sharing-management-service
+              servicePort: grpc
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress.yaml b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..634f5a8
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
+kind: Ingress
+metadata:
+  name: ${artifactId}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /sharing-management/$2
+    cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /sharing-management(/|$)(.*)
+            backend:
+              serviceName: sharing-management-service
+              servicePort: envoyhttp
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/service.yaml b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..d1e773a
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,33 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  annotations:
+    getambassador.io/config: |
+      ---
+      apiVersion: ambassador/v1
+      kind: Mapping
+      name: tenant-management-service-mapping
+      prefix: /tenant-management/
+      rewrite: ""
+      service: tenant-management-service.custos:50000
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.grpcport }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+    - port: {{ .Values.proxy.port }}
+      targetPort: envoyhttp
+      protocol: TCP
+      name: envoyhttp
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/serviceaccount.yaml b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/tests/test-connection.yaml b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/values.yaml b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..292eba6
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/values.yaml
@@ -0,0 +1,84 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+proxy:
+   repository: apachecustos/sharing-management-service-sidecar
+   tag: 1.0-SNAPSHOT
+   port: 50000
+   adminport: 9901
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/SharingManagementServiceInitializer.java b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/SharingManagementServiceInitializer.java
new file mode 100644
index 0000000..f8f5dd1
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/SharingManagementServiceInitializer.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.management;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ClientInterceptor;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
+import org.apache.custos.integration.services.commons.interceptors.LoggingInterceptor;
+import org.apache.custos.sharing.management.interceptors.AuthInterceptorImpl;
+import org.apache.custos.sharing.management.interceptors.InputValidator;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+import java.util.Stack;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "org.apache.custos")
+public class SharingManagementServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(SharingManagementServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        //   Tracing tracing1 =  Tracing.newBuilder().build();
+        return GrpcTracing.create(tracing);
+    }
+
+    //We also create a client-side interceptor and put that in the context, this interceptor can then be injected into gRPC clients and
+    //then applied to the managed channel.
+    @Bean
+    ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newClientInterceptor();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public Stack<IntegrationServiceInterceptor> getInterceptorSet(AuthInterceptorImpl authInterceptor,
+
+                                                                  InputValidator validator,
+                                                                  LoggingInterceptor loggingInterceptor) {
+        Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
+        interceptors.add(validator);
+        interceptors.add(authInterceptor);
+        interceptors.add(loggingInterceptor);
+        return interceptors;
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(Stack<IntegrationServiceInterceptor> integrationServiceInterceptors) {
+        return new ServiceInterceptor(integrationServiceInterceptors);
+    }
+
+}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/exceptions/SharingException.java b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/exceptions/SharingException.java
new file mode 100644
index 0000000..1353cbc
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/exceptions/SharingException.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.management.exceptions;
+
+public class SharingException extends RuntimeException {
+
+    public SharingException(String message, Throwable throwable) {
+        super(message, throwable);
+    }
+
+}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/AuthInterceptorImpl.java b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/AuthInterceptorImpl.java
new file mode 100644
index 0000000..1c4a274
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/AuthInterceptorImpl.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.MultiTenantAuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.sharing.service.*;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This validates custos credentials
+ */
+@Component
+public class AuthInterceptorImpl extends MultiTenantAuthInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AuthInterceptorImpl.class);
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+    public AuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient,
+                               TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+    }
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        AuthClaim authClaim;
+        if (msg instanceof EntityTypeRequest) {
+            EntityTypeRequest req = ((EntityTypeRequest) msg);
+            authClaim = validateAuth(headers, req.getClientId());
+            req = req.toBuilder()
+                    .setTenantId(authClaim.getTenantId())
+                    .setClientSec(authClaim.getIamAuthSecret())
+                    .build();
+            return (ReqT) req;
+        } else if (msg instanceof SearchRequest) {
+            SearchRequest req = ((SearchRequest) msg);
+            authClaim = validateAuth(headers, req.getClientId());
+            req = req.toBuilder()
+                    .setTenantId(authClaim.getTenantId())
+                    .setClientSec(authClaim.getIamAuthSecret())
+                    .build();
+            return (ReqT) req;
+
+        } else if (msg instanceof PermissionTypeRequest) {
+            PermissionTypeRequest req = ((PermissionTypeRequest) msg);
+            authClaim = validateAuth(headers, req.getClientId());
+            req = req.toBuilder()
+                    .setTenantId(authClaim.getTenantId())
+                    .setClientSec(authClaim.getIamAuthSecret())
+                    .build();
+            return (ReqT) req;
+
+        } else if (msg instanceof EntityRequest) {
+            EntityRequest req = ((EntityRequest) msg);
+            authClaim = validateAuth(headers, req.getClientId());
+            req = req.toBuilder()
+                    .setTenantId(authClaim.getTenantId())
+                    .setClientSec(authClaim.getIamAuthSecret())
+                    .build();
+            return (ReqT) req;
+
+        } else if (msg instanceof SharingRequest) {
+            SharingRequest req = ((SharingRequest) msg);
+            authClaim = validateAuth(headers, req.getClientId());
+            req = req.toBuilder()
+                    .setTenantId(authClaim.getTenantId())
+                    .setClientSec(authClaim.getIamAuthSecret())
+                    .build();
+            return (ReqT) req;
+
+        }
+
+        return (ReqT) msg;
+
+    }
+
+
+    private AuthClaim validateAuth(Metadata headers, String clientId) {
+        AuthClaim claim = null;
+        try {
+
+            claim = authorize(headers, clientId);
+        } catch (Exception ex) {
+            LOGGER.error(" Authorizing error " + ex.getMessage());
+            throw new NotAuthorizedException("Request is not authorized", ex);
+        }
+        if (claim == null) {
+            throw new NotAuthorizedException("Request is not authorized", null);
+        }
+        return claim;
+    }
+
+
+}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/InputValidator.java b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/InputValidator.java
new file mode 100644
index 0000000..44d5085
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/InputValidator.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.management.interceptors;
+
+
+import io.grpc.Metadata;
+import org.apache.custos.integration.core.exceptions.MissingParameterException;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.sharing.service.EntityRequest;
+import org.apache.custos.sharing.service.SharingRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class validates the  request input parameters
+ */
+@Component
+public class InputValidator implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param body
+     * @return
+     */
+    private void validate(String methodName, Object body, Metadata headers) {
+        validationAuthorizationHeader(headers);
+
+        if (methodName.equals("createEntity") || methodName.equals("updateEntity")) {
+            if (body instanceof EntityRequest) {
+                EntityRequest request = (EntityRequest) body;
+
+                if (request.getEntity() == null ||
+                        request.getEntity().getOwnerId() == null || request.getEntity().getOwnerId().equals("")) {
+                    throw new MissingParameterException("OwnerId not found", null);
+                }
+
+            } else {
+                throw new MissingParameterException("Unexpected input type for method " + methodName, null);
+            }
+
+
+        } else if (methodName.equals("shareEntityWithUsers") || methodName.equals("revokeEntitySharingFromUsers")) {
+            if (body instanceof SharingRequest) {
+                SharingRequest request = (SharingRequest) body;
+
+                if (request.getOwnerIdList() == null ||
+                        request.getOwnerIdList() == null || request.getOwnerIdList().size() == 0) {
+                    throw new MissingParameterException("OwnerId not found", null);
+                }
+
+            } else {
+                throw new MissingParameterException("Unexpected input type for method " + methodName, null);
+            }
+
+        } else if (methodName.equals("shareEntityWithGroups") || methodName.equals("revokeEntitySharingFromGroups")) {
+            if (body instanceof SharingRequest) {
+                SharingRequest request = (SharingRequest) body;
+
+                if (request.getOwnerIdList() == null ||
+                        request.getOwnerIdList() == null || request.getOwnerIdList().size() == 0) {
+                    throw new MissingParameterException("Group Id not found", null);
+                }
+
+            } else {
+                throw new MissingParameterException("Unexpected input type for method " + methodName, null);
+            }
+
+        }
+
+    }
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        validate(method, msg, headers);
+        return msg;
+    }
+
+
+    private boolean validationAuthorizationHeader(Metadata headers) {
+        if (headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER)) == null
+                || headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)) == null) {
+            throw new MissingParameterException("authorization header not available", null);
+        }
+
+        return true;
+    }
+
+}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/service/SharingManagementService.java b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/service/SharingManagementService.java
new file mode 100644
index 0000000..9c415ea
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/service/SharingManagementService.java
@@ -0,0 +1,713 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.sharing.management.service;
+
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.iam.admin.client.IamAdminServiceClient;
+import org.apache.custos.iam.service.CheckingResponse;
+import org.apache.custos.iam.service.UserRepresentation;
+import org.apache.custos.iam.service.UserSearchMetadata;
+import org.apache.custos.iam.service.UserSearchRequest;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.identity.service.GetUserManagementSATokenRequest;
+import org.apache.custos.identity.service.User;
+import org.apache.custos.integration.services.commons.utils.InterServiceModelMapper;
+import org.apache.custos.sharing.client.SharingClient;
+import org.apache.custos.sharing.management.exceptions.SharingException;
+import org.apache.custos.sharing.management.service.SharingManagementServiceGrpc.SharingManagementServiceImplBase;
+import org.apache.custos.sharing.service.Status;
+import org.apache.custos.sharing.service.*;
+import org.apache.custos.user.profile.client.UserProfileClient;
+import org.apache.custos.user.profile.service.*;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@GRpcService
+public class SharingManagementService extends SharingManagementServiceImplBase {
+
+    private static Logger LOGGER = LoggerFactory.getLogger(SharingManagementService.class);
+
+    @Autowired
+    private UserProfileClient userProfileClient;
+
+    @Autowired
+    private IamAdminServiceClient iamAdminServiceClient;
+
+    @Autowired
+    private SharingClient sharingClient;
+
+    @Autowired
+    private IdentityClient identityClient;
+
+
+    @Override
+    public void createEntityType(EntityTypeRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createEntityType in tenant " + request.getTenantId() +
+                    "  with entity type Id " + request.getEntityType().getId());
+
+            Status status = sharingClient.createEntityType(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at createEntityType " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updateEntityType(EntityTypeRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateEntityType in tenant " + request.getTenantId() +
+                    "  with entity type Id " + request.getEntityType().getId());
+
+            Status status = sharingClient.updateEntityType(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at updateEntityType " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteEntityType(EntityTypeRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteEntityType in tenant " + request.getTenantId() +
+                    "  with entity type  Id " + request.getEntityType().getId());
+
+            Status status = sharingClient.deleteEntityType(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at deleteEntityType " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getEntityType(EntityTypeRequest request, StreamObserver<EntityType> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getEntityType in tenant " + request.getTenantId() +
+                    "  with entity  type Id " + request.getEntityType().getId());
+
+            EntityType type = sharingClient.getEntityType(request);
+            responseObserver.onNext(type);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getEntityType " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getEntityTypes(SearchRequest request, StreamObserver<EntityTypes> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getEntityTypes in tenant " + request.getTenantId());
+
+            EntityTypes entityTypes = sharingClient.getEntityTypes(request);
+            responseObserver.onNext(entityTypes);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getEntityTypes " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void createPermissionType(PermissionTypeRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createPermissionType in tenant " + request.getTenantId() +
+                    "  with permission id  " + request.getPermissionType().getId());
+
+            Status status = sharingClient.createPermissionType(request);
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at createPermissionType " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updatePermissionType(PermissionTypeRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updatePermissionType in tenant " + request.getTenantId() +
+                    "  with permission id   " + request.getPermissionType().getId());
+            Status status = sharingClient.updatePermissionType(request);
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at updatePermissionType " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deletePermissionType(PermissionTypeRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deletePermissionType in tenant " + request.getTenantId() +
+                    "  with permission id  " + request.getPermissionType().getId());
+            Status status = sharingClient.deletePermissionType(request);
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at deletePermissionType " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getPermissionType(PermissionTypeRequest request, StreamObserver<PermissionType> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getPermissionType in tenant " + request.getTenantId() +
+                    "  with permission id  " + request.getPermissionType().getId());
+            PermissionType permissionType = sharingClient.getPermissionType(request);
+            responseObserver.onNext(permissionType);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getPermissionType " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getPermissionTypes(SearchRequest request, StreamObserver<PermissionTypes> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getPermissionTypes in tenant " + request.getTenantId());
+            PermissionTypes permissionTypes = sharingClient.getPermissionTypes(request);
+            responseObserver.onNext(permissionTypes);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getPermissionTypes " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void createEntity(EntityRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to createEntity in tenant " + request.getTenantId() +
+                    "  with entity id  " + request.getEntity().getId());
+
+            long tenantId = request.getTenantId();
+
+            String username = request.getEntity().getOwnerId();
+
+            String clientId = request.getClientId();
+
+            String clientSec = request.getClientSec();
+
+            String profileId = validateAndGetUserProfile(username, clientId, clientSec, tenantId);
+
+
+            Entity entity = request.getEntity();
+            entity = entity.toBuilder().setOwnerId(profileId).build();
+
+            request = request.toBuilder().setEntity(entity).build();
+
+            Status status = sharingClient.createEntity(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at createEntity " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updateEntity(EntityRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateEntity in tenant " + request.getTenantId() +
+                    "  with entity id  " + request.getEntity().getId());
+
+            long tenantId = request.getTenantId();
+
+            String username = request.getEntity().getOwnerId();
+
+            String clientId = request.getClientId();
+
+            String clientSec = request.getClientSec();
+
+            String profileId = validateAndGetUserProfile(username, clientId, clientSec, tenantId);
+
+
+            Entity entity = request.getEntity();
+            entity = entity.toBuilder().setOwnerId(profileId).build();
+
+            request = request.toBuilder().setEntity(entity).build();
+
+            Status status = sharingClient.updateEntity(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at updateEntity " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void isEntityExists(EntityRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to isEntityExists in tenant " + request.getTenantId() +
+                    "  with entity  id " + request.getEntity().getId());
+
+            Status status = sharingClient.isEntityExists(request);
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at isEntityExists " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getEntity(EntityRequest request, StreamObserver<Entity> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getEntity in tenant " + request.getTenantId() +
+                    "  with  entity  Id  " + request.getEntity().getId());
+
+            Entity entity = sharingClient.getEntity(request);
+            responseObserver.onNext(entity);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getListOfSharedUsers " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteEntity(EntityRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteEntity in tenant " + request.getTenantId() +
+                    "  with  entity Id " + request.getEntity().getId());
+
+            Status status = sharingClient.deleteEntity(request);
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at deleteEntity " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void searchEntities(SearchRequest request, StreamObserver<Entities> responseObserver) {
+        try {
+            LOGGER.debug("Request received to searchEntities in tenant " + request.getTenantId());
+
+
+            String userId = request.getOwnerId();
+
+            UserProfile profile = UserProfile.newBuilder().setUsername(userId).build();
+            UserProfileRequest profileRequest = UserProfileRequest.newBuilder()
+                    .setProfile(profile).setTenantId(request.getTenantId()).build();
+
+           GetAllGroupsResponse response =  userProfileClient.getAllGroupsOfUser(profileRequest);
+
+           List<String> associatingIds = new ArrayList<>();
+           associatingIds.add(userId);
+
+           for (Group gr: response.getGroupsList()) {
+               associatingIds.add(gr.getId());
+           }
+
+            request = request.toBuilder().addAllAssociatingIds(associatingIds).build();
+
+            Entities entities = sharingClient.searchEntities(request);
+            responseObserver.onNext(entities);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at searchEntities " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getListOfSharedUsers(SharingRequest request, StreamObserver<SharedOwners> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getListOfSharedUsers in tenant " + request.getTenantId() +
+                    "  with entity Id  " + request.getEntity().getId());
+
+            SharedOwners owners = sharingClient.getListOfSharedUsers(request);
+            responseObserver.onNext(owners);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getListOfSharedUsers " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getListOfDirectlySharedUsers(SharingRequest request, StreamObserver<SharedOwners> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getListOfDirectlySharedUsers in tenant " + request.getTenantId() +
+                    "  for entity  " + request.getEntity().getId());
+
+            SharedOwners owners = sharingClient.getListOfDirectlySharedUsers(request);
+            responseObserver.onNext(owners);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getListOfDirectlySharedUsers " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getListOfSharedGroups(SharingRequest request, StreamObserver<SharedOwners> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getListOfSharedGroups in tenant " + request.getTenantId() +
+                    "  for entity  " + request.getEntity().getId());
+
+            SharedOwners owners = sharingClient.getListOfSharedGroups(request);
+            responseObserver.onNext(owners);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getListOfSharedGroups " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getListOfDirectlySharedGroups(SharingRequest request, StreamObserver<SharedOwners> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getListOfDirectlySharedGroups in tenant " + request.getTenantId() +
+                    "  for entity  " + request.getEntity().getId());
+
+            SharedOwners owners = sharingClient.getListOfDirectlySharedGroups(request);
+            responseObserver.onNext(owners);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getListOfDirectlySharedGroups " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void shareEntityWithUsers(SharingRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to shareEntityWithUsers in tenant " + request.getTenantId() +
+                    "  for entity  " + request.getEntity().getId());
+
+            long tenantId = request.getTenantId();
+
+            String clientId = request.getClientId();
+
+            String clientSec = request.getClientSec();
+
+            for (String username : request.getOwnerIdList()) {
+
+                validateAndGetUserProfile(username, clientId, clientSec, tenantId);
+            }
+
+            Status status = sharingClient.shareEntityWithUsers(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at shareEntityWithUsers " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void shareEntityWithGroups(SharingRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to shareEntityWithGroups in tenant " + request.getTenantId() +
+                    "  with  entity Id  " + request.getEntity().getId());
+
+            long tenantId = request.getTenantId();
+
+            for (String groupId : request.getOwnerIdList()) {
+
+                validateAndGetGroupId(groupId, tenantId);
+            }
+
+            Status status = sharingClient.shareEntityWithGroups(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at shareEntityWithGroups " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void revokeEntitySharingFromUsers(SharingRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to revokeEntitySharingFromUsers in tenant " + request.getTenantId() +
+                    "  for entity  " + request.getEntity().getId());
+
+            long tenantId = request.getTenantId();
+
+            String clientId = request.getClientId();
+
+            String clientSec = request.getClientSec();
+
+            for (String username : request.getOwnerIdList()) {
+
+                validateAndGetUserProfile(username, clientId, clientSec, tenantId);
+            }
+
+            Status status = sharingClient.revokeEntitySharingFromUsers(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at revokeEntitySharingFromUsers " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void revokeEntitySharingFromGroups(SharingRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to revokeEntitySharingFromGroups in tenant " + request.getTenantId() +
+                    "  for entity  " + request.getEntity().getId());
+
+            long tenantId = request.getTenantId();
+
+
+            for (String username : request.getOwnerIdList()) {
+
+                validateAndGetGroupId(username,  tenantId);
+            }
+
+            Status status = sharingClient.revokeEntitySharingFromGroups(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at revokeEntitySharingFromGroups " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void userHasAccess(SharingRequest request, StreamObserver<Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to userHasAccess in tenant " + request.getTenantId() +
+                    "  for entity  " + request.getEntity().getId());
+
+            String clientId = request.getClientId();
+
+            String clientSec = request.getClientSec();
+
+            long tenantId = request.getTenantId();
+
+
+            for (String username : request.getOwnerIdList()) {
+
+                validateAndGetUserProfile(username, clientId, clientSec, tenantId);
+            }
+
+            UserProfile profile = UserProfile.newBuilder().setUsername(request.getOwnerId(0)).build();
+
+
+            UserProfileRequest userProfileRequest = UserProfileRequest.newBuilder()
+                    .setTenantId(tenantId)
+                    .setProfile(profile)
+                    .build();
+            GetAllGroupsResponse response = userProfileClient.getAllGroupsOfUser(userProfileRequest);
+
+            List<Group> groups = response.getGroupsList();
+
+            if (groups != null && !groups.isEmpty()) {
+
+                for (Group group : groups) {
+                    request = request.toBuilder().addOwnerId(group.getId()).build();
+                }
+            }
+
+            Status status = sharingClient.userHasAccess(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at userHasAccess " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    private String validateAndGetUserProfile(String username, String clientId, String clientSec, long tenantId) {
+
+        GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                .newBuilder()
+                .setClientId(clientId)
+                .setClientSecret(clientSec)
+                .setTenantId(tenantId)
+                .build();
+        AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+        if (token != null && token.getAccessToken() != null) {
+
+            UserSearchMetadata searchMetadata = UserSearchMetadata
+                    .newBuilder()
+                    .setUsername(username)
+                    .build();
+
+            UserSearchRequest searchRequest = UserSearchRequest
+                    .newBuilder()
+                    .setTenantId(tenantId)
+                    .setAccessToken(token.getAccessToken())
+                    .setUser(searchMetadata)
+                    .build();
+
+            CheckingResponse response = iamAdminServiceClient.isUserExist(searchRequest);
+            if (!response.getIsExist()) {
+                throw new SharingException("User " + username + " not found", null);
+            }
+
+            UserProfile userProfile = UserProfile
+                    .newBuilder()
+                    .setUsername(username)
+                    .build();
+
+            UserProfileRequest request = UserProfileRequest
+                    .newBuilder()
+                    .setProfile(userProfile)
+                    .setTenantId(tenantId)
+                    .build();
+
+            UserProfile profile = userProfileClient.getUser(request);
+
+            if (profile == null || profile.getUsername() == null || profile.getUsername().equals("")) {
+
+                UserRepresentation representation = iamAdminServiceClient.getUser(searchRequest);
+
+                UserProfile exProfile = InterServiceModelMapper.convert(representation);
+
+                UserProfileRequest req = UserProfileRequest
+                        .newBuilder()
+                        .setProfile(exProfile)
+                        .setTenantId(tenantId)
+                        .build();
+
+                userProfileClient.createUserProfile(req);
+                return exProfile.getUsername();
+
+            }
+
+            return profile.getUsername();
+
+        } else {
+
+            throw new SharingException("User management token not found ", null);
+        }
+
+
+    }
+
+    private String validateAndGetGroupId(String groupId, long tenantId) {
+
+
+        Group group = Group.newBuilder().setId(groupId).build();
+
+        GroupRequest groupRequest = GroupRequest
+                .newBuilder()
+                .setTenantId(tenantId)
+                .setGroup(group).build();
+
+        Group exGroup = userProfileClient.getGroup(groupRequest);
+
+        if (exGroup == null || exGroup.getId() == null || exGroup.getId().equals("")) {
+
+            throw new SharingException("Group with Id  " + groupId + " not found", null);
+        }
+
+        return exGroup.getId();
+
+
+    }
+
+
+}
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/proto/SharingManagementService.proto b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/proto/SharingManagementService.proto
new file mode 100644
index 0000000..74e4ca5
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/proto/SharingManagementService.proto
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.sharing.management.service;
+
+import "SharingService.proto";
+import "google/api/annotations.proto";
+
+
+service SharingManagementService {
+
+
+    rpc createEntityType (org.apache.custos.sharing.service.EntityTypeRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           post: "/sharing-management/v1.0.0/entity/type"
+        };
+
+    }
+    rpc updateEntityType (org.apache.custos.sharing.service.EntityTypeRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           put: "/sharing-management/v1.0.0/entity/type"
+        };
+
+    }
+    rpc deleteEntityType (org.apache.custos.sharing.service.EntityTypeRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           delete: "/sharing-management/v1.0.0/entity/type"
+        };
+
+    }
+    rpc getEntityType (org.apache.custos.sharing.service.EntityTypeRequest) returns (org.apache.custos.sharing.service.EntityType) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/entity/type"
+        };
+
+    }
+    rpc getEntityTypes (org.apache.custos.sharing.service.SearchRequest) returns (org.apache.custos.sharing.service.EntityTypes) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/entity/types"
+        };
+
+    }
+
+    rpc createPermissionType (org.apache.custos.sharing.service.PermissionTypeRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           post: "/sharing-management/v1.0.0/permission/type"
+        };
+
+    }
+    rpc updatePermissionType (org.apache.custos.sharing.service.PermissionTypeRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           put: "/sharing-management/v1.0.0/permission/type"
+        };
+
+    }
+    rpc deletePermissionType (org.apache.custos.sharing.service.PermissionTypeRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           delete: "/sharing-management/v1.0.0/permission/type"
+        };
+
+    }
+    rpc getPermissionType (org.apache.custos.sharing.service.PermissionTypeRequest) returns (org.apache.custos.sharing.service.PermissionType) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/permission/type"
+        };
+
+    }
+    rpc getPermissionTypes (org.apache.custos.sharing.service.SearchRequest) returns (org.apache.custos.sharing.service.PermissionTypes) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/permission/types"
+        };
+
+    }
+
+    rpc createEntity (org.apache.custos.sharing.service.EntityRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           post: "/sharing-management/v1.0.0/entity"
+        };
+
+    }
+    rpc updateEntity (org.apache.custos.sharing.service.EntityRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           put: "/sharing-management/v1.0.0/entity"
+        };
+
+    }
+    rpc isEntityExists (org.apache.custos.sharing.service.EntityRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/entity/existence"
+        };
+
+    }
+    rpc getEntity (org.apache.custos.sharing.service.EntityRequest) returns (org.apache.custos.sharing.service.Entity) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/entity"
+        };
+
+    }
+    rpc deleteEntity (org.apache.custos.sharing.service.EntityRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           delete: "/sharing-management/v1.0.0/entity"
+        };
+
+    }
+    rpc searchEntities (org.apache.custos.sharing.service.SearchRequest) returns (org.apache.custos.sharing.service.Entities) {
+        option (google.api.http) = {
+           post: "/sharing-management/v1.0.0/entities"
+        };
+
+    }
+
+
+    rpc getListOfSharedUsers (org.apache.custos.sharing.service.SharingRequest) returns (org.apache.custos.sharing.service.SharedOwners) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/users/share"
+        };
+
+    }
+    rpc getListOfDirectlySharedUsers (org.apache.custos.sharing.service.SharingRequest) returns (org.apache.custos.sharing.service.SharedOwners) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/users/share/direct"
+        };
+
+    }
+    rpc getListOfSharedGroups (org.apache.custos.sharing.service.SharingRequest) returns (org.apache.custos.sharing.service.SharedOwners) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/groups/share"
+        };
+
+    }
+    rpc getListOfDirectlySharedGroups (org.apache.custos.sharing.service.SharingRequest) returns (org.apache.custos.sharing.service.SharedOwners) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/groups/share/direct"
+        };
+
+    }
+
+    rpc shareEntityWithUsers (org.apache.custos.sharing.service.SharingRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           post: "/sharing-management/v1.0.0/users/share"
+        };
+
+    }
+    rpc shareEntityWithGroups (org.apache.custos.sharing.service.SharingRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           post: "/sharing-management/v1.0.0/groups/share"
+        };
+
+    }
+    rpc revokeEntitySharingFromUsers (org.apache.custos.sharing.service.SharingRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           delete: "/sharing-management/v1.0.0/users/share"
+        };
+
+    }
+    rpc revokeEntitySharingFromGroups (org.apache.custos.sharing.service.SharingRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           delete: "/sharing-management/v1.0.0/groups/share"
+        };
+
+    }
+    rpc userHasAccess (org.apache.custos.sharing.service.SharingRequest) returns (org.apache.custos.sharing.service.Status) {
+        option (google.api.http) = {
+           get: "/sharing-management/v1.0.0/entity/user/access"
+        };
+
+    }
+
+}
\ No newline at end of file
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/application.properties b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/application.properties
new file mode 100644
index 0000000..fe296f1
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/application.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+server.port=8080
+grpc.port=7000
+spring.application.name=sharingManagementService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
diff --git a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/bootstrap.properties b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++ b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default
diff --git a/custos-integration-services/tenant-management-service-parent/pom.xml b/custos-integration-services/tenant-management-service-parent/pom.xml
new file mode 100644
index 0000000..0dbe2b3
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>tenant-management-service-parent</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>tenant-management-service</module>
+        <module>tenant-management-service-sidecar</module>
+    </modules>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/Dockerfile b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/Dockerfile
new file mode 100644
index 0000000..5ed0d38
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/Dockerfile
@@ -0,0 +1,3 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/tenant-management-service.pb /data/tenant-management-service.pb
+COPY src/main/resources/envoy.yaml  /etc/envoy/envoy.yaml
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/pom.xml b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/pom.xml
new file mode 100644
index 0000000..4f293de
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>tenant-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>tenant-management-service-sidecar</artifactId>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/envoy.yaml b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..70dba94
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/envoy.yaml
@@ -0,0 +1,48 @@
+admin:
+  access_log_path: /tmp/admin_access.log
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+  listeners:
+    - name: main-listener
+      address:
+        socket_address: { address: 0.0.0.0, port_value: 50000 }
+      filter_chains:
+        - filters:
+            - name: envoy.http_connection_manager
+              config:
+                stat_prefix: grpc_json
+                codec_type: AUTO
+                route_config:
+                  name: local_route
+                  virtual_hosts:
+                    - name: local_service
+                      domains: ["*"]
+                      routes:
+                        - match: { prefix: "/", grpc: {} }
+                          route: { cluster: grpc-backend-services, timeout: { seconds: 60 } }
+                http_filters:
+                  - name: envoy.grpc_json_transcoder
+                    config:
+                      proto_descriptor: "/data/tenant-management-service.pb"
+                      services: ["org.apache.custos.tenant.management.service.TenantManagementService"]
+                      convert_grpc_status: true
+                      print_options:
+                        add_whitespace: true
+                        always_print_primitive_fields: true
+                        always_print_enums_as_ints: false
+                        preserve_proto_field_names: true
+                  - name: envoy.router
+
+  clusters:
+    - name: grpc-backend-services
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: localhost
+            port_value: 7000
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/generator_file b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/generator_file
new file mode 100644
index 0000000..b48b03c
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/generator_file
@@ -0,0 +1,3 @@
+protoc -I.   -Itarget/protoc-dependencies/45c49ddf3ed3308cec70daee4da0d823/ -Itarget/protoc-dependencies/8ac451ce2e503dea8ae3499dfc7022d8  --include_imports --include_source_info --descriptor_set_out=tenant_management_service.pb  src/main/proto/TenantManagementService.proto
+
+python -m grpc_tools.protoc -Isrc/main/proto/  -Itarget/protoc-dependencies/553743830f5a4c5dacb080d8dc7646f8  -Itarget/protoc-dependencies/45c49ddf3ed3308cec70daee4da0d823  --python_out=. --grpc_python_out=. src/main/proto/AgentManagementService.proto
\ No newline at end of file
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/tenant-management-service.pb b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/tenant-management-service.pb
new file mode 100644
index 0000000..90cb160
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service-sidecar/src/main/resources/tenant-management-service.pb
Binary files differ
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/Dockerfile b/custos-integration-services/tenant-management-service-parent/tenant-management-service/Dockerfile
new file mode 100644
index 0000000..6457ff8
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/pom.xml b/custos-integration-services/tenant-management-service-parent/tenant-management-service/pom.xml
new file mode 100644
index 0000000..ddd6a8f
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/pom.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>tenant-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>tenant-management-service</artifactId>
+
+
+
+    <dependencies>
+          <dependency>
+              <groupId>org.apache.custos</groupId>
+              <artifactId>tenant-profile-core-service-client-stub</artifactId>
+              <version>${project.version}</version>
+          </dependency>
+          <dependency>
+              <groupId>org.apache.custos</groupId>
+              <artifactId>iam-admin-core-service-client-stub</artifactId>
+              <version>${project.version}</version>
+          </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>federated-authentication-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+          <dependency>
+              <groupId>org.apache.custos</groupId>
+              <artifactId>custos-integration-core</artifactId>
+              <version>${project.version}</version>
+          </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+          <dependency>
+              <groupId>org.springframework.boot</groupId>
+              <artifactId>spring-boot-starter-web</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>org.springframework.boot</groupId>
+              <artifactId>spring-boot-starter-actuator</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>org.springframework.cloud</groupId>
+              <artifactId>spring-cloud-starter-config</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>org.springframework.cloud</groupId>
+              <artifactId>spring-cloud-starter-sleuth</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>org.springframework.cloud</groupId>
+              <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>io.zipkin.brave</groupId>
+              <artifactId>brave-instrumentation-grpc</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>io.micrometer</groupId>
+              <artifactId>micrometer-registry-prometheus</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>io.github.lognet</groupId>
+              <artifactId>grpc-spring-boot-starter</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>io.grpc</groupId>
+              <artifactId>grpc-stub</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>io.grpc</groupId>
+              <artifactId>grpc-protobuf</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>io.grpc</groupId>
+              <artifactId>grpc-netty</artifactId>
+          </dependency>
+          <dependency>
+              <groupId>com.google.api.grpc</groupId>
+              <artifactId>proto-google-common-protos</artifactId>
+          </dependency>
+      </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/.helmignore b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/Chart.yaml b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..f898c3b
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos tenant registration service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/NOTES.txt b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/_helpers.tpl b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/deployment.yaml b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..2fe140f
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,78 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+            - name: grpc
+              containerPort: {{ .Values.service.grpcport }}
+              protocol: TCP
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+        - name: {{ .Chart.Name }}-envoy-proxy
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.proxy.repository }}:{{ .Values.proxy.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: envoyhttp
+              containerPort: {{ .Values.proxy.port }}
+              protocol: TCP
+            - name: adminhttp
+              containerPort: {{ .Values.proxy.adminport }}
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: {{ .Values.service.port }}
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/ingress-grpc.yaml b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/ingress-grpc.yaml
new file mode 100644
index 0000000..afc2746
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/ingress-grpc.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: "nginx"
+    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
+    cert-manager.io/cluster-issuer: letsencrypt-production
+  name: ${artifactId}-ingress-grpc
+spec:
+  rules:
+     - host: custos.scigap.org
+       http:
+        paths:
+          - path: /org.apache.custos.tenant.management.service.TenantManagementService(/|$)(.*)
+            backend:
+              serviceName: tenant-management-service
+              servicePort: grpc
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/ingress.yaml b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..98f3b28
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
+kind: Ingress
+metadata:
+  name: ${artifactId}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /tenant-management/$2
+    cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /tenant-management(/|$)(.*)
+            backend:
+              serviceName: tenant-management-service
+              servicePort: envoyhttp
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/service.yaml b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..d1e773a
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,33 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  annotations:
+    getambassador.io/config: |
+      ---
+      apiVersion: ambassador/v1
+      kind: Mapping
+      name: tenant-management-service-mapping
+      prefix: /tenant-management/
+      rewrite: ""
+      service: tenant-management-service.custos:50000
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.grpcport }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+    - port: {{ .Values.proxy.port }}
+      targetPort: envoyhttp
+      protocol: TCP
+      name: envoyhttp
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/serviceaccount.yaml b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/tests/test-connection.yaml b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/values.yaml b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..059067a
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/helm/values.yaml
@@ -0,0 +1,84 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+proxy:
+   repository: apachecustos/tenant-management-service-sidecar
+   tag: 1.0-SNAPSHOT
+   port: 50000
+   adminport: 9901
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/TenantManagementServiceInitializer.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/TenantManagementServiceInitializer.java
new file mode 100644
index 0000000..0cb128a
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/TenantManagementServiceInitializer.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.management;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ClientInterceptor;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
+import org.apache.custos.integration.services.commons.interceptors.LoggingInterceptor;
+import org.apache.custos.tenant.management.interceptors.AuthInterceptorImpl;
+import org.apache.custos.tenant.management.interceptors.DynamicRegistrationValidator;
+import org.apache.custos.tenant.management.interceptors.InputValidator;
+import org.apache.custos.tenant.management.interceptors.SuperTenantRestrictedOperationsInterceptorImpl;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+import java.util.*;
+
+
+@SpringBootApplication
+@ComponentScan(basePackages = "org.apache.custos")
+public class TenantManagementServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(TenantManagementServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        //   Tracing tracing1 =  Tracing.newBuilder().build();
+        return GrpcTracing.create(tracing);
+    }
+
+    //We also create a client-side interceptor and put that in the context, this interceptor can then be injected into gRPC clients and
+    //then applied to the managed channel.
+    @Bean
+    ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newClientInterceptor();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public Stack<IntegrationServiceInterceptor> getInterceptorSet(AuthInterceptorImpl authInterceptor,
+                                                                  DynamicRegistrationValidator registrationValidator,
+                                                                  InputValidator validator, SuperTenantRestrictedOperationsInterceptorImpl adminOperationsInterceptor,
+                                                                   LoggingInterceptor loggingInterceptor) {
+        Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
+        interceptors.add(validator);
+        interceptors.add(authInterceptor);
+        interceptors.add(adminOperationsInterceptor);
+        interceptors.add(registrationValidator);
+        interceptors.add(loggingInterceptor);
+
+        return interceptors;
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(Stack<IntegrationServiceInterceptor> integrationServiceInterceptors) {
+        return new ServiceInterceptor(integrationServiceInterceptors);
+    }
+
+}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/exceptions/MissingParameterException.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/exceptions/MissingParameterException.java
new file mode 100644
index 0000000..153aa2e
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/exceptions/MissingParameterException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.management.exceptions;
+
+/**
+ * Missing Parameter
+ */
+public class MissingParameterException extends RuntimeException {
+
+   public MissingParameterException(String msg, Throwable e) {
+      super(msg,e);
+   }
+}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/AuthInterceptorImpl.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/AuthInterceptorImpl.java
new file mode 100644
index 0000000..593c5ed
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/AuthInterceptorImpl.java
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.federated.authentication.service.CacheManipulationRequest;
+import org.apache.custos.iam.service.AddProtocolMapperRequest;
+import org.apache.custos.iam.service.AddRolesRequest;
+import org.apache.custos.iam.service.EventPersistenceRequest;
+import org.apache.custos.iam.service.GetRolesRequest;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.management.service.Credentials;
+import org.apache.custos.tenant.management.service.DeleteTenantRequest;
+import org.apache.custos.tenant.management.service.GetTenantRequest;
+import org.apache.custos.tenant.management.service.UpdateTenantRequest;
+import org.apache.custos.tenant.management.utils.Constants;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.tenant.profile.service.GetTenantsRequest;
+import org.apache.custos.tenant.profile.service.Tenant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This validates custos credentials
+ */
+@Component
+public class AuthInterceptorImpl extends AuthInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AuthInterceptorImpl.class);
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+    public AuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient,
+                               TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+    }
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+
+
+        if (method.equals("createTenant")) {
+
+            AuthClaim claim = authorize(headers);
+            if (claim == null) {
+                return msg;
+            } else {
+
+                return (ReqT) ((Tenant) msg).toBuilder().setParentTenantId(claim.getTenantId()).build();
+            }
+
+        } else if (method.equals("getTenant")) {
+
+            AuthClaim claim = validateAuth(headers);
+
+            GetTenantRequest tenantRequest = ((GetTenantRequest) msg);
+
+            Credentials credentials = getCredentials(claim);
+
+
+            return (ReqT) tenantRequest.toBuilder()
+                    .setTenantId(claim.getTenantId()).setCredentials(credentials).build();
+        } else if (method.equals("updateTenant")) {
+
+
+            AuthClaim claim = validateAuth(headers);
+
+            UpdateTenantRequest tenantRequest = ((UpdateTenantRequest) msg);
+
+            Credentials credentials = getCredentials(claim);
+
+            return (ReqT) tenantRequest.toBuilder()
+                    .setTenantId(claim.getTenantId()).setCredentials(credentials).build();
+        } else if (method.equals("deleteTenant")) {
+
+            AuthClaim claim = validateAuth(headers);
+
+            DeleteTenantRequest tenantRequest = ((DeleteTenantRequest) msg);
+
+            Credentials credentials = getCredentials(claim);
+
+
+            return (ReqT) tenantRequest.toBuilder()
+                    .setTenantId(claim.getTenantId()).setCredentials(credentials).build();
+        } else if (method.equals("addTenantRoles")) {
+
+            AuthClaim claim = validateAuth(headers);
+
+            AddRolesRequest rolesRequest = ((AddRolesRequest) msg);
+
+            return (ReqT) rolesRequest.toBuilder()
+                    .setTenantId(claim.getTenantId()).setClientId(claim.getCustosId()).build();
+        } else if (method.equals("getTenantRoles")) {
+
+            AuthClaim claim = validateAuth(headers);
+
+            GetRolesRequest rolesRequest = ((GetRolesRequest) msg);
+
+            return (ReqT) rolesRequest.toBuilder()
+                    .setTenantId(claim.getTenantId()).setClientId(claim.getCustosId()).build();
+        } else if (method.equals("addProtocolMapper")) {
+
+            AuthClaim claim = validateAuth(headers);
+
+            AddProtocolMapperRequest rolesRequest = ((AddProtocolMapperRequest) msg);
+
+            return (ReqT) rolesRequest.toBuilder()
+                    .setTenantId(claim.getTenantId()).setClientId(claim.getCustosId()).build();
+        } else if (method.equals("configureEventPersistence")) {
+
+            AuthClaim claim = validateAuth(headers);
+
+            EventPersistenceRequest rolesRequest = ((EventPersistenceRequest) msg);
+
+            return (ReqT) rolesRequest.toBuilder()
+                    .setTenantId(claim.getTenantId()).setPerformedBy("Tenant Admin")
+                    .build();
+        } else if (method.equals("getChildTenants")) {
+
+            AuthClaim claim = validateAuth(headers);
+
+            GetTenantsRequest tenantsRequest = ((GetTenantsRequest) msg);
+
+            return (ReqT) tenantsRequest.toBuilder()
+                    .setParentId(claim.getTenantId()).build();
+        } else if (method.equals("getAllTenantsForUser")) {
+            validateAuth(headers);
+            return msg;
+        } else if (method.equals("getFromCache") || method.equals("getInstitutions")) {
+            AuthClaim claim = validateAuth(headers);
+
+            CacheManipulationRequest request = ((CacheManipulationRequest) msg);
+            return (ReqT) request.toBuilder().setTenantId(claim.getTenantId()).build();
+
+        } else if (method.equals("addToCache") || method.equals("removeFromCache")) {
+            AuthClaim claim = validateAuth(headers);
+            AuthClaim userClaim = validateUserToken(headers);
+
+            CacheManipulationRequest.Builder request = ((CacheManipulationRequest) msg).toBuilder();
+
+            if (userClaim != null) {
+                request = request.setPerformedBy(userClaim.getUsername());
+            }
+
+            return (ReqT) request.setTenantId(claim.getTenantId()).build();
+
+        }
+        return msg;
+    }
+
+
+    private AuthClaim validateAuth(Metadata headers) {
+        AuthClaim claim = null;
+        try {
+            claim = authorize(headers);
+        } catch (Exception ex) {
+            LOGGER.error(" Authorizing error " + ex.getMessage());
+            throw new NotAuthorizedException("Request is not authorized", ex);
+        }
+        if (claim == null) {
+            throw new NotAuthorizedException("Request is not authorized", null);
+        }
+        return claim;
+    }
+
+
+    private AuthClaim validateUserToken(Metadata headers) {
+        AuthClaim claim = null;
+        try {
+            String usertoken = headers.get(Metadata.Key.of(Constants.USER_TOKEN, Metadata.ASCII_STRING_MARSHALLER));
+            if (usertoken == null) {
+                return null;
+            }
+
+            claim = authorizeUsingUserToken(usertoken);
+        } catch (Exception ex) {
+            LOGGER.error(" Authorizing error " + ex.getMessage());
+            throw new NotAuthorizedException("Request is not authorized", ex);
+        }
+        if (claim == null) {
+            throw new NotAuthorizedException("Request is not authorized", null);
+        }
+        return claim;
+
+
+    }
+
+    private Credentials getCredentials(AuthClaim claim) {
+        return Credentials.newBuilder()
+                .setCustosClientId(claim.getCustosId())
+                .setCustosClientSecret(claim.getCustosSecret())
+                .setCustosClientIdIssuedAt(claim.getCustosIdIssuedAt())
+                .setCustosClientSecretExpiredAt(claim.getCustosSecretExpiredAt())
+                .setIamClientId(claim.getIamAuthId())
+                .setIamClientSecret(claim.getIamAuthSecret())
+                .setCiLogonClientId(claim.getCiLogonId())
+                .setCiLogonClientSecret(claim.getCiLogonSecret()).build();
+
+    }
+}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/DynamicRegistrationValidator.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/DynamicRegistrationValidator.java
new file mode 100644
index 0000000..cdfe8b7
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/DynamicRegistrationValidator.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.credential.store.service.CredentialMetadata;
+import org.apache.custos.credential.store.service.GetCredentialRequest;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.management.service.DeleteTenantRequest;
+import org.apache.custos.tenant.management.service.GetTenantRequest;
+import org.apache.custos.tenant.management.service.UpdateTenantRequest;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.tenant.profile.service.Tenant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class validates the  conditions that should be satisfied by the Dynamic Registration Protocol
+ */
+@Component
+public class DynamicRegistrationValidator extends AuthInterceptor implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(DynamicRegistrationValidator.class);
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+    private TenantProfileClient tenantProfileClient;
+
+    public DynamicRegistrationValidator(CredentialStoreServiceClient credentialStoreServiceClient,
+                                        TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+        this.tenantProfileClient = tenantProfileClient;
+    }
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+
+
+        if (method.equals("getTenant")) {
+            GetTenantRequest tenantRequest = ((GetTenantRequest) msg);
+
+            String clientId = tenantRequest.getClientId();
+
+            GetCredentialRequest request = GetCredentialRequest.newBuilder()
+                    .setId(clientId)
+                    .build();
+            CredentialMetadata metadata = credentialStoreServiceClient.getCustosCredentialFromClientId(request);
+
+            if (metadata == null || metadata.getOwnerId() == 0) {
+                throw new NotAuthorizedException("Invalid client_id", null);
+            }
+
+            Tenant tenant = validateTenant(metadata.getOwnerId(), tenantRequest.getTenantId(), headers);
+            return (ReqT) tenantRequest.toBuilder().setTenantId(tenant != null ? tenant.getTenantId() :
+                    tenantRequest.getTenantId()).setTenant(tenant).build();
+
+        } else if (method.equals("createTenant")) {
+
+            Tenant tenantRequest = ((Tenant) msg);
+
+            if (tenantRequest.getParentTenantId() > 0) {
+                validateTenant(tenantRequest.getParentTenantId(), tenantRequest.getParentTenantId(), headers);
+            }
+
+        } else if (method.equals("updateTenant")) {
+
+
+            UpdateTenantRequest tenantRequest = ((UpdateTenantRequest) msg);
+
+            String clientId = tenantRequest.getClientId();
+
+            if (clientId == null || clientId.trim().equals("")) {
+                clientId = tenantRequest.getBody().getClientId();
+            }
+
+            GetCredentialRequest request = GetCredentialRequest.newBuilder()
+                    .setId(clientId)
+                    .build();
+            CredentialMetadata metadata = credentialStoreServiceClient.getCustosCredentialFromClientId(request);
+
+            if (metadata == null || metadata.getOwnerId() == 0) {
+                throw new NotAuthorizedException("Invalid client_id", null);
+            }
+
+
+            Tenant tenant = validateTenant(metadata.getOwnerId(), tenantRequest.getTenantId(), headers);
+
+            return (ReqT) tenantRequest.toBuilder().setTenantId(tenant.getTenantId()).setClientId(clientId).build();
+
+        } else if (method.equals("deleteTenant")) {
+
+
+            DeleteTenantRequest tenantRequest = ((DeleteTenantRequest) msg);
+
+            String clientId = tenantRequest.getClientId();
+
+            GetCredentialRequest request = GetCredentialRequest.newBuilder()
+                    .setId(clientId)
+                    .build();
+            CredentialMetadata metadata = credentialStoreServiceClient.getCustosCredentialFromClientId(request);
+
+            if (metadata == null || metadata.getOwnerId() == 0) {
+                throw new NotAuthorizedException("Invalid client_id", null);
+            }
+
+
+            Tenant tenant = validateTenant(metadata.getOwnerId(), tenantRequest.getTenantId(), headers);
+
+            return (ReqT) tenantRequest.toBuilder().setTenantId(tenant.getTenantId()).build();
+
+        }
+        return msg;
+    }
+
+
+    private Tenant validateTenant(long ownerId, long parentTenant, Metadata headers) {
+
+        org.apache.custos.tenant.profile.service.GetTenantRequest tenantReq =
+                org.apache.custos.tenant.profile.service.GetTenantRequest
+                        .newBuilder().setTenantId(ownerId).build();
+
+        org.apache.custos.tenant.profile.service.GetTenantResponse response =
+                tenantProfileClient.getTenant(tenantReq);
+
+        Tenant tenant = response.getTenant();
+
+        AuthClaim authClaim = authorize(headers);
+
+        if (authClaim != null && authClaim.isSuperTenant()) {
+            return tenant;
+        }
+
+        if (tenant == null || (tenant.getParentTenantId() != 0 && tenant.getParentTenantId() != parentTenant)) {
+            throw new NotAuthorizedException("Not a valid admin client", null);
+        }
+
+        return tenant;
+    }
+}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/InputValidator.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/InputValidator.java
new file mode 100644
index 0000000..1643788
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/InputValidator.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.management.interceptors;
+
+
+import io.grpc.Metadata;
+import org.apache.custos.iam.service.AddRolesRequest;
+import org.apache.custos.iam.service.RoleRepresentation;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.tenant.management.exceptions.MissingParameterException;
+import org.apache.custos.tenant.management.service.DeleteTenantRequest;
+import org.apache.custos.tenant.management.service.GetTenantRequest;
+import org.apache.custos.tenant.management.service.UpdateTenantRequest;
+import org.apache.custos.tenant.management.utils.Constants;
+import org.apache.custos.tenant.profile.service.UpdateStatusRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * This class validates the  request input parameters
+ */
+@Component
+public class InputValidator implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param body
+     * @return
+     */
+    private void validate(String methodName, Object body, Metadata headers) {
+
+        switch (methodName) {
+            case "getCredentials":
+                validateGetCredentials(headers, methodName);
+                break;
+            case "getTenant":
+                validateGetTenant(headers, body, methodName);
+                break;
+            case "updateTenant":
+                validateUpdateTenant(headers, body, methodName);
+                break;
+            case "deleteTenant":
+                validateDeleteTenant(headers, body, methodName);
+                break;
+            case "addTenantRoles":
+                validateAddRoleToTenant(headers, body, methodName);
+                break;
+            case "addProtocolMapper":
+            case "configureEventPersistence":
+                validateAddProtocolMapper(headers, body, methodName);
+                break;
+            case "updateTenantStatus":
+                validateUpdateTenantStatus(headers, body, methodName);
+                break;
+            case "addToCache":
+            case "removeFromCache":
+            case "getFromCache":
+            case "getInstitutions":
+            case "getTenantRoles":
+                validationAuthorizationHeader(headers);
+                break;
+            default:
+        }
+    }
+
+
+    private boolean validateGetCredentials(Metadata headers, String method) {
+        return validationAuthorizationHeader(headers);
+
+    }
+
+    private boolean validateGetTenant(Metadata headers, Object body, String method) {
+        validationAuthorizationHeader(headers);
+        GetTenantRequest tenantRequest = ((GetTenantRequest) body);
+
+        String clientId = tenantRequest.getClientId();
+
+        if (clientId == null || clientId.trim().equals("")) {
+            throw new MissingParameterException("client_id should not be null", null);
+        }
+        return true;
+    }
+
+    private boolean validateUpdateTenant(Metadata headers, Object body, String method) {
+        validationAuthorizationHeader(headers);
+
+
+        UpdateTenantRequest tenantRequest = ((UpdateTenantRequest) body);
+
+        String clientId = tenantRequest.getClientId();
+
+        if (clientId == null || clientId.trim().equals("")) {
+            clientId = tenantRequest.getBody().getClientId();
+        }
+
+        if (clientId == null || clientId.trim().equals("")) {
+            throw new MissingParameterException("client_id should not be null", null);
+        }
+        return true;
+    }
+
+    private boolean validateDeleteTenant(Metadata headers, Object body, String method) {
+        validationAuthorizationHeader(headers);
+
+
+        DeleteTenantRequest tenantRequest = ((DeleteTenantRequest) body);
+
+        String clientId = tenantRequest.getClientId();
+
+
+        if (clientId == null || clientId.trim().equals("")) {
+            throw new MissingParameterException("client_id should not be null", null);
+        }
+        return true;
+    }
+
+    private boolean validateAddRoleToTenant(Metadata headers, Object body, String method) {
+        validationAuthorizationHeader(headers);
+
+
+        AddRolesRequest addRolesRequest = ((AddRolesRequest) body);
+
+        List<RoleRepresentation> rolesList = addRolesRequest.getRolesList();
+
+        if (rolesList == null || rolesList.isEmpty()) {
+            throw new MissingParameterException("Roles should not be null", null);
+        }
+
+        for (RoleRepresentation roleRepresentation : rolesList) {
+            if (roleRepresentation.getName() == null || roleRepresentation.getName().trim().equals("")) {
+                throw new MissingParameterException("Roles name should not be null", null);
+            }
+            if (roleRepresentation.getDescription() == null || roleRepresentation.getDescription().trim().equals("")) {
+                throw new MissingParameterException("Description should not be null", null);
+            }
+        }
+
+
+        return true;
+    }
+
+    private boolean validateAddProtocolMapper(Metadata headers, Object body, String method) {
+        validationAuthorizationHeader(headers);
+
+        return true;
+    }
+
+    private boolean validateUpdateTenantStatus(Metadata headers, Object body, String method) {
+        boolean isSuperTenant = ((UpdateStatusRequest) body).getSuperTenant();
+        if (!isSuperTenant) {
+            validationAuthorizationHeader(headers);
+        }
+
+        UpdateStatusRequest updateStatusRequest = ((UpdateStatusRequest) body);
+
+        if (updateStatusRequest.getClientId() == null || updateStatusRequest.getClientId().trim().equals("")) {
+            throw new MissingParameterException("Client Id should not be null", null);
+        }
+        return true;
+    }
+
+
+    private boolean validationAuthorizationHeader(Metadata headers) {
+        if (headers.get(Metadata.Key.of(Constants.AUTHORIZATION_HEADER, Metadata.ASCII_STRING_MARSHALLER)) == null
+                || headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)) == null) {
+            throw new MissingParameterException("authorization header not available", null);
+        }
+
+        return true;
+    }
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        validate(method, msg, headers);
+        return msg;
+    }
+}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/SuperTenantRestrictedOperationsInterceptorImpl.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/SuperTenantRestrictedOperationsInterceptorImpl.java
new file mode 100644
index 0000000..cdaafd1
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/interceptors/SuperTenantRestrictedOperationsInterceptorImpl.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.management.service.Credentials;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.tenant.profile.service.UpdateStatusRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SuperTenantRestrictedOperationsInterceptorImpl extends AuthInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SuperTenantRestrictedOperationsInterceptorImpl.class);
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+
+    public SuperTenantRestrictedOperationsInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient,
+                                                          TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+
+        if (method.equals("updateTenantStatus")) {
+            if ( !((UpdateStatusRequest)msg).getSuperTenant() ) {
+                AuthClaim claim = null;
+                String token = getToken(headers);
+                try {
+                    claim = authorizeUsingUserToken(headers);
+                } catch (Exception ex) {
+                    LOGGER.error(" Authorizing error " + ex.getMessage());
+                    throw new NotAuthorizedException("Request is not authorized", ex);
+                }
+                if (claim == null || !claim.isSuperTenant() || !claim.isAdmin()) {
+                    throw new NotAuthorizedException("Request is not authorized", null);
+                }
+                return (ReqT) ((UpdateStatusRequest) msg).toBuilder().setUpdatedBy(claim.getPerformedBy())
+                        .setAccessToken(token).build();
+            }
+            return msg;
+
+        } else if (method.equals("getAllTenants")) {
+            AuthClaim claim = null;
+            try {
+                claim = authorize(headers);
+                LOGGER.info("Claim "+ claim);
+                LOGGER.info("Claim Auth "+ claim.isSuperTenant());
+            } catch (Exception ex) {
+                throw new NotAuthorizedException("Request is not authorized", ex);
+            }
+            if (claim == null || !claim.isSuperTenant()) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            return msg;
+
+        }
+
+        return msg;
+    }
+
+
+    private Credentials getCredentials(AuthClaim claim) {
+        return Credentials.newBuilder()
+                .setCustosClientId(claim.getCustosId())
+                .setCustosClientSecret(claim.getCustosSecret())
+                .setCustosClientIdIssuedAt(claim.getCustosIdIssuedAt())
+                .setCustosClientSecretExpiredAt(claim.getCustosSecretExpiredAt())
+                .setIamClientId(claim.getIamAuthId())
+                .setIamClientSecret(claim.getIamAuthSecret())
+                .setCiLogonClientId(claim.getCiLogonId())
+                .setCiLogonClientSecret(claim.getCiLogonSecret()).build();
+
+    }
+}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/service/TenantManagementService.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/service/TenantManagementService.java
new file mode 100644
index 0000000..7db8d5b
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/service/TenantManagementService.java
@@ -0,0 +1,805 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.management.service;
+
+import io.grpc.Context;
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.credential.store.service.*;
+import org.apache.custos.federated.authentication.client.FederatedAuthenticationClient;
+import org.apache.custos.federated.authentication.service.CacheManipulationRequest;
+import org.apache.custos.federated.authentication.service.DeleteClientRequest;
+import org.apache.custos.federated.authentication.service.GetInstitutionsIdsAsResponse;
+import org.apache.custos.federated.authentication.service.GetInstitutionsResponse;
+import org.apache.custos.iam.admin.client.IamAdminServiceClient;
+import org.apache.custos.iam.service.OperationStatus;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.identity.service.GetUserManagementSATokenRequest;
+import org.apache.custos.integration.core.ServiceCallback;
+import org.apache.custos.integration.core.ServiceChain;
+import org.apache.custos.integration.core.ServiceException;
+import org.apache.custos.tenant.management.service.TenantManagementServiceGrpc.TenantManagementServiceImplBase;
+import org.apache.custos.tenant.management.tasks.TenantActivationTask;
+import org.apache.custos.tenant.management.utils.Constants;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.tenant.profile.service.*;
+import org.apache.custos.user.profile.client.UserProfileClient;
+import org.apache.custos.user.profile.service.UserProfile;
+import org.apache.custos.user.profile.service.UserProfileRequest;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+@GRpcService
+public class TenantManagementService extends TenantManagementServiceImplBase {
+    private static final Logger LOGGER = LoggerFactory.getLogger(TenantManagementService.class);
+
+
+    @Autowired
+    private TenantProfileClient profileClient;
+
+    @Autowired
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+    @Autowired
+    private IamAdminServiceClient iamAdminServiceClient;
+
+    @Autowired
+    private FederatedAuthenticationClient federatedAuthenticationClient;
+
+    @Autowired
+    private TenantActivationTask<UpdateStatusResponse, UpdateStatusResponse> tenantActivationTask;
+
+    @Autowired
+    private UserProfileClient userProfileClient;
+
+    @Autowired
+    private IdentityClient identityClient;
+
+
+    @Override
+    public void createTenant(Tenant request, StreamObserver<CreateTenantResponse> responseObserver) {
+        try {
+            LOGGER.debug("Tenant requested for " + request.getClientName());
+
+            Tenant response = profileClient.addTenant(request);
+
+            long tenantId = response.getTenantId();
+
+            GetNewCustosCredentialRequest req = GetNewCustosCredentialRequest.newBuilder().setOwnerId(tenantId).build();
+
+            CredentialMetadata resp = credentialStoreServiceClient.getNewCustosCredentials(req);
+
+            String message = "Use Base64 encoded clientId:clientSecret as auth token for authorization, " +
+                    "Credentials are activated after admin approval";
+            boolean isTenantActivated = false;
+
+            if (request.getParentTenantId() > 0) {
+                request = request.toBuilder().setTenantId(tenantId).build();
+
+
+                tenantActivationTask.activateTenant(request, request.getRequesterEmail(), false);
+
+                isTenantActivated = true;
+
+                message = "Credentials are activated";
+
+            } else {
+                CredentialMetadata metadata = CredentialMetadata
+                        .newBuilder()
+                        .setId(request.getAdminUsername())
+                        .setSecret(request.getAdminPassword())
+                        .setOwnerId(tenantId)
+                        .setType(Type.INDIVIDUAL)
+                        .build();
+
+                credentialStoreServiceClient.putCredential(metadata);
+
+            }
+
+            String tenantBaseURI = Constants.TENANT_BASE_URI + "?client_id=" + resp.getId();
+
+
+            CreateTenantResponse tenantResponse = CreateTenantResponse.newBuilder()
+                    .setClientId(resp.getId())
+                    .setClientSecret(resp.getSecret())
+                    .setClientIdIssuedAt(resp.getClientIdIssuedAt())
+                    .setClientSecretExpiresAt(resp.getClientSecretExpiredAt())
+                    .setTokenEndpointAuthMethod(Constants.CLIENT_SECRET_BASIC)
+                    .setIsActivated(isTenantActivated)
+                    .setRegistrationClientUri(tenantBaseURI)
+                    .setMsg(message)
+                    .build();
+
+            responseObserver.onNext(tenantResponse);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at createTenant " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INVALID_ARGUMENT.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getTenant(GetTenantRequest request, StreamObserver<GetTenantResponse> responseObserver) {
+        try {
+
+            Tenant tenant = request.getTenant(); // retrieved cached tenant from interceptors
+
+            if (tenant == null) {
+                org.apache.custos.tenant.profile.service.GetTenantRequest tenantReq =
+                        org.apache.custos.tenant.profile.service.GetTenantRequest
+                                .newBuilder().setTenantId(request.getTenantId()).build();
+
+                org.apache.custos.tenant.profile.service.GetTenantResponse response =
+                        profileClient.getTenant(tenantReq);
+                tenant = response.getTenant();
+            }
+
+            double clientIdIssuedAt = request.getCredentials().getCustosClientIdIssuedAt();
+
+            if (!request.getCredentials().getCustosClientId().equals(request.getClientId())) {
+
+                GetCredentialRequest credentialRequest = GetCredentialRequest.newBuilder()
+                        .setOwnerId(tenant.getTenantId())
+                        .setId(request.getClientId())
+                        .setType(Type.CUSTOS).build();
+
+                clientIdIssuedAt = credentialStoreServiceClient.
+                        getCredential(credentialRequest).getClientIdIssuedAt();
+            }
+
+
+            String[] grantTypes = {Constants.AUTHORIZATION_CODE};
+
+            GetTenantResponse tenantResponse = GetTenantResponse.newBuilder()
+                    .setClientId(request.getClientId())
+                    .setAdminEmail(tenant.getAdminEmail())
+                    .setAdminFirstName(tenant.getAdminFirstName())
+                    .setAdminLastName(tenant.getAdminLastName())
+                    .setAdminUsername(tenant.getAdminUsername())
+                    .setRequesterEmail(tenant.getRequesterEmail())
+                    .setApplicationType(tenant.getApplicationType())
+                    .setClientName(tenant.getClientName())
+                    .setClientUri(tenant.getClientUri())
+                    .setComment(tenant.getComment())
+                    .setDomain(tenant.getDomain())
+                    .setExampleExtensionParameter(tenant.getExampleExtensionParameter())
+                    .setJwksUri(tenant.getJwksUri())
+                    .addAllContacts(tenant.getContactsList())
+                    .addAllRedirectUris(tenant.getRedirectUrisList())
+                    .setLogoUri(tenant.getLogoUri())
+                    .setPolicyUri(tenant.getPolicyUri())
+                    .setTosUri(tenant.getTosUri())
+                    .setScope(tenant.getScope())
+                    .setSoftwareId(tenant.getSoftwareId())
+                    .setSoftwareVersion(tenant.getSoftwareVersion())
+                    .addAllGrantTypes(Arrays.asList(grantTypes))
+                    .setClientIdIssuedAt(clientIdIssuedAt)
+                    .build();
+            responseObserver.onNext(tenantResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getTenant " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INVALID_ARGUMENT.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void updateTenant(UpdateTenantRequest request, StreamObserver<GetTenantResponse> responseObserver) {
+
+        try {
+            Tenant tenant = request.getBody();
+
+            tenant = tenant.toBuilder().setTenantId(request.getTenantId()).build();
+
+            Tenant updateTenant = profileClient.updateTenant(tenant);
+
+            tenantActivationTask.activateTenant(updateTenant, Constants.GATEWAY_ADMIN, true);
+
+            double clientIdIssuedAt = request.getCredentials().getCustosClientIdIssuedAt();
+
+
+            if (!request.getCredentials().getCustosClientId().equals(request.getClientId())) {
+
+                GetCredentialRequest credentialRequest = GetCredentialRequest.newBuilder()
+                        .setOwnerId(tenant.getTenantId())
+                        .setId(request.getClientId())
+                        .setType(Type.CUSTOS).build();
+
+                clientIdIssuedAt = credentialStoreServiceClient.
+                        getCredential(credentialRequest).getClientIdIssuedAt();
+            }
+
+
+            String[] grantTypes = {Constants.AUTHORIZATION_CODE,
+                    Constants.CLIENT_CREDENTIALS,
+                    Constants.PASSWORD_GRANT_TYPE,
+                    Constants.REFRESH_TOKEN};
+
+            GetCredentialRequest credentialRequest = GetCredentialRequest.newBuilder()
+                    .setOwnerId(tenant.getTenantId())
+                    .setId(request.getClientId())
+                    .setType(Type.IAM).build();
+
+            CredentialMetadata iamCredential = credentialStoreServiceClient.
+                    getCredential(credentialRequest);
+
+
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(iamCredential.getId())
+                    .setClientSecret(iamCredential.getSecret())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+                UserSearchMetadata userSearchMetadata = UserSearchMetadata
+                        .newBuilder()
+                        .setUsername(tenant.getAdminUsername())
+                        .build();
+
+                UserSearchRequest searchRequest = UserSearchRequest.newBuilder().
+                        setTenantId(request.getTenantId())
+                        .setPerformedBy(Constants.GATEWAY_ADMIN)
+                        .setAccessToken(token.getAccessToken())
+                        .setUser(userSearchMetadata)
+                        .build();
+
+                UserRepresentation userRepresentation = iamAdminServiceClient.getUser(searchRequest);
+
+                UserProfile profile = convertToProfile(userRepresentation);
+
+                UserProfileRequest userProfileRequest = UserProfileRequest
+                        .newBuilder()
+                        .setProfile(profile)
+                        .setPerformedBy(Constants.GATEWAY_ADMIN)
+                        .setTenantId(request.getTenantId())
+                        .build();
+
+                UserProfile userProfile = userProfileClient.getUser(userProfileRequest);
+
+                if (userProfile == null || userProfile.getUsername().equals("")) {
+                    userProfileClient.createUserProfile(userProfileRequest);
+                } else {
+                    userProfileClient.updateUserProfile(userProfileRequest);
+                }
+
+
+            }
+
+            GetTenantResponse tenantResponse = GetTenantResponse.newBuilder()
+                    .setClientId(request.getClientId())
+                    .setAdminEmail(tenant.getAdminEmail())
+                    .setAdminFirstName(tenant.getAdminFirstName())
+                    .setAdminLastName(tenant.getAdminLastName())
+                    .setRequesterEmail(tenant.getRequesterEmail())
+                    .setApplicationType(tenant.getApplicationType())
+                    .setClientName(tenant.getClientName())
+                    .setClientUri(tenant.getClientUri())
+                    .setComment(tenant.getComment())
+                    .setDomain(tenant.getDomain())
+                    .setExampleExtensionParameter(tenant.getExampleExtensionParameter())
+                    .setJwksUri(tenant.getJwksUri())
+                    .addAllContacts(tenant.getContactsList())
+                    .addAllRedirectUris(tenant.getRedirectUrisList())
+                    .setLogoUri(tenant.getLogoUri())
+                    .setPolicyUri(tenant.getPolicyUri())
+                    .setTosUri(tenant.getTosUri())
+                    .setScope(tenant.getScope())
+                    .setSoftwareId(tenant.getSoftwareId())
+                    .setSoftwareVersion(tenant.getSoftwareVersion())
+                    .addAllGrantTypes(Arrays.asList(grantTypes))
+                    .setClientIdIssuedAt(clientIdIssuedAt)
+                    .build();
+
+            responseObserver.onNext(tenantResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at updateTenant " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INVALID_ARGUMENT.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void deleteTenant(DeleteTenantRequest request, StreamObserver<com.google.protobuf.Empty> responseObserver) {
+        try {
+            org.apache.custos.tenant.profile.service.UpdateStatusRequest updateTenantRequest =
+                    org.apache.custos.tenant.profile.service.UpdateStatusRequest
+                            .newBuilder()
+                            .setStatus(TenantStatus.DEACTIVATED)
+                            .setTenantId(request.getTenantId())
+                            .setUpdatedBy(Constants.GATEWAY_ADMIN)
+                            .build();
+
+            profileClient.updateTenantStatus(updateTenantRequest);
+
+            Credentials credentials = request.getCredentials();
+
+
+            if (!request.getCredentials().getCustosClientId().equals(request.getClientId())) {
+
+                GetAllCredentialsRequest credentialRequest = GetAllCredentialsRequest.newBuilder()
+                        .setOwnerId(request.getTenantId())
+                        .build();
+
+                GetAllCredentialsResponse response = credentialStoreServiceClient.getAllCredentials(credentialRequest);
+
+                if (response.getSecretListCount() > 0) {
+
+                    Credentials.Builder creBuilder = Credentials.newBuilder();
+                    response.getSecretListList().forEach(metadata -> {
+
+                                if (metadata.getType() == Type.CUSTOS) {
+                                    creBuilder.setCustosClientId(metadata.getId())
+                                            .setCustosClientSecret(metadata.getSecret())
+                                            .setCustosClientIdIssuedAt(metadata.getClientIdIssuedAt())
+                                            .setCustosClientSecretExpiredAt(metadata.getClientSecretExpiredAt());
+                                } else if (metadata.getType() == Type.IAM) {
+                                    creBuilder.setIamClientId(metadata.getId())
+                                            .setIamClientSecret(metadata.getSecret());
+
+
+                                } else if (metadata.getType() == Type.CILOGON) {
+                                    creBuilder.setCiLogonClientId(metadata.getId())
+                                            .setCiLogonClientSecret(metadata.getSecret());
+                                }
+
+                            }
+
+                    );
+
+                    credentials = creBuilder.build();
+                }
+
+            }
+
+
+            DeleteClientRequest clientRequest = DeleteClientRequest.newBuilder()
+                    .setClientId(credentials.getCiLogonClientId())
+                    .setTenantId(request.getTenantId())
+                    .setPerformedBy(Constants.GATEWAY_ADMIN)
+                    .build();
+            federatedAuthenticationClient.deleteClient(clientRequest);
+
+
+            org.apache.custos.iam.service.DeleteTenantRequest tenantRequest = org.apache.custos.iam.service.
+                    DeleteTenantRequest.newBuilder().setTenantId(request.getTenantId()).build();
+            iamAdminServiceClient.deleteTenant(tenantRequest);
+
+            DeleteCredentialRequest deleteCredentialRequest = DeleteCredentialRequest
+                    .newBuilder().setOwnerId(request.getTenantId()).build();
+
+            credentialStoreServiceClient.deleteCredential(deleteCredentialRequest);
+
+            responseObserver.onNext(com.google.protobuf.Empty.newBuilder().build());
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at deleteTenant " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INVALID_ARGUMENT.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void addTenantRoles(AddRolesRequest request, StreamObserver<AllRoles> responseObserver) {
+        try {
+            AllRoles allRoles = iamAdminServiceClient.addRolesToTenant(request);
+
+            responseObserver.onNext(allRoles);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at addTenantRoles " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getTenantRoles(GetRolesRequest request, StreamObserver<AllRoles> responseObserver) {
+        try {
+            AllRoles allRoles = iamAdminServiceClient.getRolesOfTenant(request);
+
+            responseObserver.onNext(allRoles);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at getTenantRoles " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addProtocolMapper(AddProtocolMapperRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            OperationStatus allRoles = iamAdminServiceClient.addProtocolMapper(request);
+
+            responseObserver.onNext(allRoles);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at addProtocolMapper " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void configureEventPersistence(EventPersistenceRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            OperationStatus allRoles = iamAdminServiceClient.configureEventPersistence(request);
+
+            responseObserver.onNext(allRoles);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred at configureEventPersistence " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getAllTenants(GetTenantsRequest request, StreamObserver<GetAllTenantsResponse> responseObserver) {
+        try {
+            GetAllTenantsResponse response = profileClient.getAllTenants(request);
+
+            if (response != null && !response.getTenantList().isEmpty()) {
+                List<Tenant> tenantList = new ArrayList<>();
+
+                for (Tenant tenant : response.getTenantList()) {
+
+                    GetCredentialRequest credentialRequest = GetCredentialRequest.newBuilder()
+                            .setOwnerId(tenant.getTenantId())
+                            .setType(Type.CUSTOS).build();
+
+                    CredentialMetadata metadata = credentialStoreServiceClient.
+                            getCredential(credentialRequest);
+
+                    tenant = tenant.toBuilder().setClientId(metadata.getId()).build();
+                    tenantList.add(tenant);
+
+                }
+
+                response = response.toBuilder().clearTenant().addAllTenant(tenantList).build();
+            }
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAllTenants " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getChildTenants(GetTenantsRequest request, StreamObserver<GetAllTenantsResponse> responseObserver) {
+        try {
+            GetAllTenantsResponse response = profileClient.getAllTenants(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred at getChildTenants " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getAllTenantsForUser(GetAllTenantsForUserRequest request, StreamObserver<GetAllTenantsForUserResponse> responseObserver) {
+        try {
+            GetAllTenantsForUserResponse response = profileClient.getAllTenantsForUser(request);
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred at getAllTenantsForUser " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void updateTenantStatus(UpdateStatusRequest request, StreamObserver<UpdateStatusResponse> responseObserver) {
+        try {
+
+            GetCredentialRequest credentialRequest = GetCredentialRequest.newBuilder().
+                    setId(request.getClientId())
+                    .setType(Type.CUSTOS)
+                    .build();
+
+            CredentialMetadata metadata = credentialStoreServiceClient.getCustosCredentialFromClientId(credentialRequest);
+
+            if (metadata != null) {
+                request = request.toBuilder().setTenantId(metadata.getOwnerId()).build();
+                UpdateStatusResponse response = profileClient.updateTenantStatus(request);
+
+                if (request.getStatus().equals(TenantStatus.ACTIVE)) {
+
+                    Context ctx = Context.current().fork();
+                    // Set ctx as the current context within the Runnable
+                    UpdateStatusRequest finalRequest = request;
+                    ctx.run(() -> {
+                        ServiceCallback callback = new ServiceCallback() {
+                            @Override
+                            public void onCompleted(Object obj) {
+                                org.apache.custos.tenant.profile.service.GetTenantRequest tenantRequest =
+                                        org.apache.custos.tenant.profile.service.GetTenantRequest
+                                                .newBuilder()
+                                                .setTenantId(metadata.getOwnerId())
+                                                .build();
+
+                                org.apache.custos.tenant.profile.service.GetTenantResponse tenantResponse =
+                                        profileClient.getTenant(tenantRequest);
+                                Tenant savedTenant = tenantResponse.getTenant();
+
+                                GetCredentialRequest credentialRequest = GetCredentialRequest.newBuilder()
+                                        .setOwnerId(metadata.getOwnerId())
+                                        .setType(Type.IAM)
+                                        .build();
+
+                                CredentialMetadata iamMeta = credentialStoreServiceClient.getCredential(credentialRequest);
+
+                                GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                                        .newBuilder()
+                                        .setClientId(iamMeta.getId())
+                                        .setClientSecret(iamMeta.getSecret())
+                                        .setTenantId(metadata.getOwnerId())
+                                        .build();
+                                AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+                                if (token != null && token.getAccessToken() != null) {
+
+
+                                    UserSearchMetadata userSearchMetadata = UserSearchMetadata
+                                            .newBuilder()
+                                            .setUsername(savedTenant.getAdminUsername())
+                                            .build();
+
+                                    UserSearchRequest searchRequest = UserSearchRequest.newBuilder().
+                                            setTenantId(savedTenant.getTenantId())
+                                            .setPerformedBy(finalRequest.getUpdatedBy())
+                                            .setAccessToken(token.getAccessToken())
+                                            .setUser(userSearchMetadata)
+                                            .build();
+
+                                    UserRepresentation userRepresentation = iamAdminServiceClient.getUser(searchRequest);
+
+                                    UserProfile profile = convertToProfile(userRepresentation);
+
+                                    UserProfileRequest userProfileRequest = UserProfileRequest
+                                            .newBuilder()
+                                            .setProfile(profile)
+                                            .setPerformedBy(finalRequest.getUpdatedBy())
+                                            .setTenantId(finalRequest.getTenantId())
+                                            .build();
+
+
+                                    UserProfile userProfile = userProfileClient.getUser(userProfileRequest);
+
+                                    if (userProfile == null || userProfile.getUsername().equals("")) {
+                                        userProfileClient.createUserProfile(userProfileRequest);
+                                    } else {
+                                        userProfileClient.updateUserProfile(userProfileRequest);
+                                    }
+
+                                    responseObserver.onNext(response);
+                                    responseObserver.onCompleted();
+                                } else {
+                                    String msg = "Tenant Activation task failed, cannot find IAM server credentials";
+                                    LOGGER.error(msg);
+                                    responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
+
+                                }
+                            }
+
+                            @Override
+                            public void onError(ServiceException ex) {
+                                String msg = "Tenant Activation task failed " + ex;
+                                LOGGER.error(msg);
+                                org.apache.custos.tenant.profile.service.UpdateStatusRequest updateTenantRequest =
+                                        org.apache.custos.tenant.profile.service.UpdateStatusRequest.newBuilder()
+                                                .setTenantId(finalRequest.getTenantId())
+                                                .setStatus(TenantStatus.CANCELLED)
+                                                .setUpdatedBy(Constants.SYSTEM)
+                                                .build();
+                                profileClient.updateTenantStatus(updateTenantRequest);
+                                responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
+                            }
+                        };
+
+                        ServiceChain chain = ServiceChain.newBuilder(tenantActivationTask, callback).build();
+
+                        chain.serve(response);
+                    });
+                } else {
+                    responseObserver.onNext(response);
+                    responseObserver.onCompleted();
+                }
+            } else {
+                String msg = "Cannot find a Tenant with given client id " + request.getTenantId();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Tenant update task failed for tenant " + request.getTenantId() + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void addToCache(CacheManipulationRequest request,
+                           StreamObserver<org.apache.custos.federated.authentication.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to add to cache for tenant  " + request.getTenantId());
+
+
+            org.apache.custos.federated.authentication.service.Status status = federatedAuthenticationClient.addToCache(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred calling addToCache method for tenant  " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeFromCache(CacheManipulationRequest request,
+                                StreamObserver<org.apache.custos.federated.authentication.service.Status> responseObserver) {
+        try {
+            LOGGER.debug("Request received to removeFromCache for tenant  " + request.getTenantId());
+            org.apache.custos.federated.authentication.service.Status status = federatedAuthenticationClient.removeFromCache(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred calling removeFromCache method for tenant  " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getFromCache(CacheManipulationRequest request,
+                             StreamObserver<GetInstitutionsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getFromCache for tenant  " + request.getTenantId());
+
+            GetInstitutionsResponse status = federatedAuthenticationClient.getFromCache(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+            String msg = "Error occurred calling getFromCache method for tenant  " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getInstitutions(CacheManipulationRequest request,
+                                StreamObserver<GetInstitutionsResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getInstitutions for tenant  " + request.getTenantId());
+            GetInstitutionsResponse status = federatedAuthenticationClient.getInstitutions(request);
+
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred calling getInstitutions method for tenant  " + request.getTenantId() + " reason :" + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getTenantStatusUpdateAuditTrail(GetAuditTrailRequest request, StreamObserver<GetStatusUpdateAuditTrailResponse> responseObserver) {
+
+        GetStatusUpdateAuditTrailResponse response = profileClient.getStatusUpdateAuditTrail(request);
+        responseObserver.onNext(response);
+        responseObserver.onCompleted();
+    }
+
+    @Override
+    public void getTenantAttributeUpdateAuditTrail(GetAuditTrailRequest request, StreamObserver<GetAttributeUpdateAuditTrailResponse> responseObserver) {
+        GetAttributeUpdateAuditTrailResponse response = profileClient.getAttributeUpdateAuditTrail(request);
+
+        responseObserver.onNext(response);
+        responseObserver.onCompleted();
+    }
+
+
+    private UserProfile convertToProfile(UserRepresentation representation) {
+        UserProfile.Builder profileBuilder = UserProfile.newBuilder();
+
+
+        if (representation.getRealmRolesCount() > 0) {
+            profileBuilder.addAllRealmRoles(representation.getRealmRolesList());
+
+        }
+
+        if (representation.getClientRolesCount() > 0) {
+            profileBuilder.addAllClientRoles(representation.getClientRolesList());
+
+        }
+
+        if (representation.getAttributesCount() > 0) {
+            List<UserAttribute> attributeList = representation.getAttributesList();
+
+            List<org.apache.custos.user.profile.service.UserAttribute> userAtrList = new ArrayList<>();
+            attributeList.forEach(atr -> {
+                org.apache.custos.user.profile.service.UserAttribute userAttribute =
+                        org.apache.custos.user.profile.service.UserAttribute
+                                .newBuilder()
+                                .setKey(atr.getKey())
+                                .addAllValue(atr.getValuesList())
+                                .build();
+
+                userAtrList.add(userAttribute);
+            });
+            profileBuilder.addAllAttributes(userAtrList);
+
+
+        }
+
+        profileBuilder.setUsername(representation.getUsername().toLowerCase());
+        profileBuilder.setFirstName(representation.getFirstName());
+        profileBuilder.setLastName(representation.getLastName());
+        profileBuilder.setEmail(representation.getEmail());
+
+        return profileBuilder.build();
+
+    }
+}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/tasks/TenantActivationTask.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/tasks/TenantActivationTask.java
new file mode 100644
index 0000000..1aba81b
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/tasks/TenantActivationTask.java
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.management.tasks;
+
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.credential.store.service.CredentialMetadata;
+import org.apache.custos.credential.store.service.GetCredentialRequest;
+import org.apache.custos.credential.store.service.Type;
+import org.apache.custos.federated.authentication.client.FederatedAuthenticationClient;
+import org.apache.custos.federated.authentication.service.ClientMetadata;
+import org.apache.custos.federated.authentication.service.RegisterClientResponse;
+import org.apache.custos.iam.admin.client.IamAdminServiceClient;
+import org.apache.custos.iam.service.ConfigureFederateIDPRequest;
+import org.apache.custos.iam.service.FederatedIDPs;
+import org.apache.custos.iam.service.SetUpTenantRequest;
+import org.apache.custos.iam.service.SetUpTenantResponse;
+import org.apache.custos.integration.core.ServiceException;
+import org.apache.custos.integration.core.ServiceTaskImpl;
+import org.apache.custos.tenant.management.utils.Constants;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.tenant.profile.service.*;
+import org.apache.custos.user.profile.client.UserProfileClient;
+import org.apache.custos.user.profile.service.UserProfile;
+import org.apache.custos.user.profile.service.UserProfileRequest;
+import org.apache.custos.user.profile.service.UserStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@Component
+public class TenantActivationTask<T, U> extends ServiceTaskImpl<T, U> {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(TenantActivationTask.class);
+
+
+    @Autowired
+    private IamAdminServiceClient iamAdminServiceClient;
+
+    @Autowired
+    private FederatedAuthenticationClient federatedAuthenticationClient;
+
+    @Autowired
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+    @Autowired
+    private TenantProfileClient profileClient;
+
+
+    @Override
+    public void invokeService(T data) {
+        try {
+            if (data instanceof UpdateStatusResponse) {
+                long tenantId = ((UpdateStatusResponse) data).getTenantId();
+                LOGGER.debug("Invoking tenant activation task for tenant " + tenantId);
+
+                GetTenantRequest tenantRequest = GetTenantRequest
+                        .newBuilder()
+                        .setTenantId(tenantId)
+                        .build();
+
+                GetTenantResponse tenantRes = profileClient.getTenant(tenantRequest);
+
+                Tenant tenant = tenantRes.getTenant();
+
+                if (tenant != null) {
+
+                    GetCredentialRequest request = GetCredentialRequest
+                            .newBuilder()
+                            .setId(tenant.getAdminUsername())
+                            .setOwnerId(tenantId)
+                            .setType(Type.INDIVIDUAL)
+                            .build();
+                    CredentialMetadata metadata = credentialStoreServiceClient.getCredential(request);
+
+                    if (metadata != null && metadata.getSecret() != null) {
+
+                        Tenant newTenant = tenant.toBuilder().setAdminPassword(metadata.getSecret()).build();
+
+
+                        GetCredentialRequest iamClientReques = GetCredentialRequest
+                                .newBuilder()
+                                .setOwnerId(tenantId)
+                                .setType(Type.IAM)
+                                .build();
+
+                        CredentialMetadata iamMetadata = credentialStoreServiceClient.getCredential(iamClientReques);
+
+                        UpdateStatusResponse response = null;
+                        if (iamMetadata == null || iamMetadata.getId() == null || iamMetadata.getId().equals("")) {
+                             response = this.activateTenant(newTenant, Constants.SYSTEM, false);
+                        } else {
+                            response = this.activateTenant(newTenant, Constants.SYSTEM, true);
+                        }
+
+                        invokeNextTask((U) response);
+
+                    } else {
+                        String msg = "Admin password not found  for admin  " + tenant.getAdminUsername();
+                        LOGGER.error(msg);
+                        getServiceCallback().onError(new ServiceException(msg, null, null));
+                    }
+                } else {
+                    String msg = "Tenant not found  for Id  " + tenantId;
+                    LOGGER.error(msg);
+                    getServiceCallback().onError(new ServiceException(msg, null, null));
+                }
+            } else {
+                String msg = "Invalid payload type ";
+                LOGGER.error(msg);
+                getServiceCallback().onError(new ServiceException(msg, null, null));
+            }
+        } catch (Exception ex) {
+            String msg = "Error occurred  " + ex.getCause();
+            LOGGER.error(msg, ex);
+            getServiceCallback().onError(new ServiceException(msg, ex.getCause(), null));
+        }
+    }
+
+
+    public UpdateStatusResponse activateTenant(Tenant tenant, String performedBy, boolean update) {
+
+
+        GetCredentialRequest getCreRe = GetCredentialRequest.newBuilder().
+                setOwnerId(tenant.getTenantId())
+                .setType(Type.CUSTOS)
+                .build();
+
+        CredentialMetadata metadata = credentialStoreServiceClient.getCredential(getCreRe);
+
+        SetUpTenantRequest setUpTenantRequest = SetUpTenantRequest
+                .newBuilder()
+                .setTenantId(tenant.getTenantId())
+                .setTenantName(tenant.getClientName())
+                .setAdminFirstname(tenant.getAdminFirstName())
+                .setAdminLastname(tenant.getAdminLastName())
+                .setAdminEmail(tenant.getAdminEmail())
+                .addAllRedirectURIs(tenant.getRedirectUrisList())
+                .setAdminPassword(tenant.getAdminPassword())
+                .setAdminUsername(tenant.getAdminUsername())
+                .setRequesterEmail(tenant.getRequesterEmail())
+                .setTenantURL(tenant.getClientUri())
+                .setCustosClientId(metadata.getId())
+                .build();
+
+        SetUpTenantResponse iamResponse = null;
+        if (update) {
+            iamResponse = iamAdminServiceClient.updateTenant(setUpTenantRequest);
+        } else {
+
+            iamResponse = iamAdminServiceClient.setUPTenant(setUpTenantRequest);
+        }
+
+        CredentialMetadata credentialMetadata = CredentialMetadata
+                .newBuilder()
+                .setId(iamResponse.getClientId())
+                .setSecret(iamResponse.getClientSecret())
+                .setOwnerId(tenant.getTenantId())
+                .setType(Type.IAM)
+                .build();
+
+        credentialStoreServiceClient.putCredential(credentialMetadata);
+
+        String comment = (tenant.getComment() == null || tenant.getComment().trim().equals("")) ?
+                "Created by custos" : tenant.getComment();
+
+
+        String[] scopes = tenant.getScope() != null ? tenant.getScope().split(" ") : new String[0];
+
+        GetCredentialRequest credentialRequest = GetCredentialRequest.newBuilder()
+                .setOwnerId(tenant.getTenantId())
+                .setType(Type.CILOGON).build();
+
+        String ciLogonRedirectURI = iamAdminServiceClient.getIamServerURL() + "realms" + "/" + tenant.getTenantId() + "/" + "broker" + "/" + "oidc" + "/" + "endpoint";
+
+
+        List<String> arrayList = new ArrayList<>();
+        arrayList.add(ciLogonRedirectURI);
+
+        ClientMetadata.Builder clientMetadataBuilder = ClientMetadata
+                .newBuilder()
+                .setTenantId(tenant.getTenantId())
+                .setTenantName(tenant.getClientName())
+                .setTenantURI(tenant.getClientUri())
+                .setComment(comment)
+                .addAllScope(Arrays.asList(scopes))
+                .addAllRedirectURIs(arrayList)
+                .addAllContacts(tenant.getContactsList())
+                .setPerformedBy(performedBy);
+
+
+        CredentialMetadata creMeta = credentialStoreServiceClient.
+                getCredential(credentialRequest);
+
+        clientMetadataBuilder.setClientId(creMeta.getId());
+
+
+        if (!update) {
+            RegisterClientResponse registerClientResponse = federatedAuthenticationClient
+                    .addClient(clientMetadataBuilder.build());
+
+
+            CredentialMetadata credentialMetadataCILogon = CredentialMetadata
+                    .newBuilder()
+                    .setId(registerClientResponse.getClientId())
+                    .setSecret(registerClientResponse.getClientSecret())
+                    .setOwnerId(tenant.getTenantId())
+                    .setType(Type.CILOGON)
+                    .build();
+
+            credentialStoreServiceClient.putCredential(credentialMetadataCILogon);
+
+
+            ConfigureFederateIDPRequest request = ConfigureFederateIDPRequest
+                    .newBuilder()
+                    .setTenantId(tenant.getTenantId())
+                    .setClientID(registerClientResponse.getClientId())
+                    .setClientSec(registerClientResponse.getClientSecret())
+                    .setScope(tenant.getScope())
+                    .setRequesterEmail(tenant.getRequesterEmail())
+                    .setType(FederatedIDPs.CILOGON)
+                    .build();
+            iamAdminServiceClient.configureFederatedIDP(request);
+        }
+
+        org.apache.custos.tenant.profile.service.UpdateStatusRequest updateTenantRequest =
+                org.apache.custos.tenant.profile.service.UpdateStatusRequest.newBuilder()
+                        .setTenantId(tenant.getTenantId())
+                        .setStatus(TenantStatus.ACTIVE)
+                        .setUpdatedBy(Constants.SYSTEM)
+                        .build();
+        return profileClient.updateTenantStatus(updateTenantRequest);
+    }
+
+}
\ No newline at end of file
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/utils/Constants.java b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/utils/Constants.java
new file mode 100644
index 0000000..21d332c
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/java/org/apache/custos/tenant/management/utils/Constants.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.tenant.management.utils;
+
+/**
+ * This is constant class use for tenant management service
+ */
+public final class Constants {
+    public static final String SYSTEM = "SYSTEM";
+    public static final String GATEWAY_ADMIN = "GATEWAY_ADMIN";
+    public static final String CLIENT_SECRET_BASIC = "client_secret_basic";
+    public static final String TENANT_BASE_URI = "https://custos.scigap.org:32036/tenant-management/v1.0.0/oauth2/tenant";
+    public static final String AUTHORIZATION_CODE = "code";
+    public static final String CLIENT_CREDENTIALS = "client-credentials";
+    public static final String PASSWORD_GRANT_TYPE = "password";
+    public static final String REFRESH_TOKEN = "refresh-token";
+
+    public static final String AUTHORIZATION_HEADER = "authorization";
+    public static final String USER_TOKEN = "user-token";
+
+}
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/proto/TenantManagementService.proto b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/proto/TenantManagementService.proto
new file mode 100644
index 0000000..eeba841
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/proto/TenantManagementService.proto
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.tenant.management.service;
+
+import "google/api/annotations.proto";
+import "TenantProfileService.proto";
+import "google/rpc/error_details.proto";
+import "google/protobuf/empty.proto";
+import "IamAdminService.proto";
+import "FederatedAuthenticationService.proto";
+
+
+message CreateTenantResponse {
+    string client_id = 1;
+    string client_secret = 2;
+    bool is_activated = 3;
+    double client_id_issued_at = 4;
+    double client_secret_expires_at = 5;
+    string registration_client_uri = 6;
+    string token_endpoint_auth_method = 17;
+    string msg = 7;
+}
+
+message GetTenantResponse {
+    string client_id = 1;
+    string client_name = 2;
+    string requester_email = 3;
+    string admin_first_name = 4;
+    string admin_last_name = 5;
+    string admin_email = 6;
+    repeated string contacts = 7;
+    repeated string redirect_uris = 8;
+    repeated string grant_types = 9;
+    double client_id_issued_at = 10;
+    string client_uri = 11;
+    string scope = 12;
+    string domain = 13;
+    string comment = 14;
+    string logo_uri = 15;
+    string application_type = 16;
+    string jwks_uri = 17;
+    string example_extension_parameter = 18;
+    string tos_uri = 19;
+    string policy_uri = 20;
+    map<string, string> jwks = 21;
+    string software_id = 22;
+    string software_version = 23;
+    string admin_username = 24;
+}
+
+
+message GetTenantRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    org.apache.custos.tenant.profile.service.Tenant tenant = 4;
+    Credentials credentials = 5;
+}
+
+
+message Credentials {
+    string iam_client_id = 1;
+    string iam_client_secret = 2;
+    string ci_logon_client_id = 3;
+    string ci_logon_client_secret = 4;
+    string custos_client_id = 5;
+    string custos_client_secret = 6;
+    double custos_client_id_issued_at = 7;
+    double custos_client_secret_expired_at = 8;
+}
+
+message UpdateTenantRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    Credentials credentials = 3;
+    org.apache.custos.tenant.profile.service.Tenant body = 4;
+}
+
+
+message DeleteTenantRequest {
+    string client_id = 1;
+    int64 tenant_id = 2;
+    Credentials credentials = 3;
+    org.apache.custos.tenant.profile.service.Tenant body = 4;
+}
+
+
+message GetCredentialsRequest {
+    int64 tenantId = 1;
+}
+
+message GetCredentialsResponse {
+    string iamClientId = 1;
+    string iamClientSecret = 2;
+    string ciLogonClientId = 3;
+    string ciLogonClientSecret = 4;
+}
+
+service TenantManagementService {
+
+    rpc createTenant (org.apache.custos.tenant.profile.service.Tenant) returns (CreateTenantResponse) {
+        option (google.api.http) = {
+           post: "/tenant-management/v1.0.0/oauth2/tenant"
+         };
+    }
+
+    rpc getTenant (GetTenantRequest) returns (GetTenantResponse) {
+        option (google.api.http) = {
+           get: "/tenant-management/v1.0.0/oauth2/tenant"
+        };
+    }
+
+    rpc updateTenant (UpdateTenantRequest) returns (GetTenantResponse) {
+        option (google.api.http) = {
+           put: "/tenant-management/v1.0.0/oauth2/tenant"
+           body: "body"
+        };
+    }
+
+
+    rpc deleteTenant (DeleteTenantRequest) returns (google.protobuf.Empty) {
+        option (google.api.http) = {
+           delete: "/tenant-management/v1.0.0/oauth2/tenant"
+        };
+    }
+
+    rpc addTenantRoles (org.apache.custos.iam.service.AddRolesRequest) returns (org.apache.custos.iam.service.AllRoles) {
+        option (google.api.http) = {
+           post: "/tenant-management/v1.0.0/roles"
+        };
+    }
+
+    rpc getTenantRoles (org.apache.custos.iam.service.GetRolesRequest) returns (org.apache.custos.iam.service.AllRoles) {
+        option (google.api.http) = {
+           get: "/tenant-management/v1.0.0/roles"
+        };
+    }
+
+    rpc addProtocolMapper (org.apache.custos.iam.service.AddProtocolMapperRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/tenant-management/v1.0.0/protocol/mapper"
+        };
+    }
+
+    rpc configureEventPersistence (org.apache.custos.iam.service.EventPersistenceRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/tenant-management/v1.0.0/events"
+        };
+    }
+
+
+    rpc updateTenantStatus (org.apache.custos.tenant.profile.service.UpdateStatusRequest) returns (org.apache.custos.tenant.profile.service.UpdateStatusResponse) {
+        option (google.api.http) = {
+           post: "/tenant-management/v1.0.0/status"
+        };
+    }
+
+    rpc getAllTenants (org.apache.custos.tenant.profile.service.GetTenantsRequest) returns (org.apache.custos.tenant.profile.service.GetAllTenantsResponse) {
+        option (google.api.http) = {
+           get: "/tenant-management/v1.0.0/tenants"
+        };
+    }
+
+    rpc getChildTenants (org.apache.custos.tenant.profile.service.GetTenantsRequest) returns (org.apache.custos.tenant.profile.service.GetAllTenantsResponse) {
+        option (google.api.http) = {
+           get: "/tenant-management/v1.0.0/child/tenants"
+        };
+    }
+
+    rpc getAllTenantsForUser (org.apache.custos.tenant.profile.service.GetAllTenantsForUserRequest) returns (org.apache.custos.tenant.profile.service.GetAllTenantsForUserResponse) {
+        option (google.api.http) = {
+           get: "/tenant-management/v1.0.0/tenants/{requesterEmail}"
+        };
+    }
+    rpc getTenantStatusUpdateAuditTrail (org.apache.custos.tenant.profile.service.GetAuditTrailRequest) returns (org.apache.custos.tenant.profile.service.GetStatusUpdateAuditTrailResponse) {
+        option (google.api.http) = {
+           get: "/tenant-management/v1.0.0/audit/status/{tenantId}"
+        };
+    }
+    rpc getTenantAttributeUpdateAuditTrail (org.apache.custos.tenant.profile.service.GetAuditTrailRequest) returns (org.apache.custos.tenant.profile.service.GetAttributeUpdateAuditTrailResponse) {
+        option (google.api.http) = {
+           get: "/tenant-management/v1.0.0/audit/attributes/{tenantId}"
+        };
+    }
+
+
+    rpc addToCache (org.apache.custos.federated.authentication.service.CacheManipulationRequest) returns (org.apache.custos.federated.authentication.service.Status) {
+        option (google.api.http) = {
+           post: "/tenant-management/v1.0.0/cache/institutions/CILogon"
+        };
+
+    }
+    rpc removeFromCache (org.apache.custos.federated.authentication.service.CacheManipulationRequest) returns (org.apache.custos.federated.authentication.service.Status) {
+        option (google.api.http) = {
+           delete: "/tenant-management/v1.0.0/cache/institutions/CILogon"
+        };
+
+    }
+    rpc getFromCache (org.apache.custos.federated.authentication.service.CacheManipulationRequest) returns (org.apache.custos.federated.authentication.service.GetInstitutionsResponse) {
+        option (google.api.http) = {
+           get: "/tenant-management/v1.0.0/cache/institutions/CILogon"
+        };
+
+    }
+    rpc getInstitutions (org.apache.custos.federated.authentication.service.CacheManipulationRequest) returns (org.apache.custos.federated.authentication.service.GetInstitutionsResponse) {
+        option (google.api.http) = {
+           get: "/tenant-management/v1.0.0/institutions/CILogon"
+        };
+    }
+
+
+}
\ No newline at end of file
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/resources/application.properties b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/resources/application.properties
new file mode 100644
index 0000000..49b6041
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/resources/application.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+server.port=8080
+grpc.port=7000
+spring.application.name=tenantManagementService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
diff --git a/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/resources/bootstrap.properties b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++ b/custos-integration-services/tenant-management-service-parent/tenant-management-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default
diff --git a/custos-integration-services/user-management-service-parent/pom.xml b/custos-integration-services/user-management-service-parent/pom.xml
new file mode 100644
index 0000000..5c8d26b
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos-integration-services</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>user-management-service-parent</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>user-management-service</module>
+        <module>user-management-service-sidecar</module>
+    </modules>
+
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/user-management-service-parent/user-management-service-sidecar/Dockerfile b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/Dockerfile
new file mode 100644
index 0000000..f90d22d
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/Dockerfile
@@ -0,0 +1,3 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/user-management-service.pb /data/user-management-service.pb
+COPY src/main/resources/envoy.yaml  /etc/envoy/envoy.yaml
diff --git a/custos-integration-services/user-management-service-parent/user-management-service-sidecar/pom.xml b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/pom.xml
new file mode 100644
index 0000000..b1d2b77
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>user-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>user-management-service-sidecar</artifactId>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/envoy.yaml b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..ac54427
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/envoy.yaml
@@ -0,0 +1,48 @@
+admin:
+  access_log_path: /tmp/admin_access.log
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+  listeners:
+    - name: main-listener
+      address:
+        socket_address: { address: 0.0.0.0, port_value: 50000 }
+      filter_chains:
+        - filters:
+            - name: envoy.http_connection_manager
+              config:
+                stat_prefix: grpc_json
+                codec_type: AUTO
+                route_config:
+                  name: local_route
+                  virtual_hosts:
+                    - name: local_service
+                      domains: ["*"]
+                      routes:
+                        - match: { prefix: "/", grpc: {} }
+                          route: { cluster: grpc-backend-services, timeout: { seconds: 60 } }
+                http_filters:
+                  - name: envoy.grpc_json_transcoder
+                    config:
+                      proto_descriptor: "/data/user-management-service.pb"
+                      services: ["org.apache.custos.user.management.service.UserManagementService"]
+                      convert_grpc_status: true
+                      print_options:
+                        add_whitespace: true
+                        always_print_primitive_fields: true
+                        always_print_enums_as_ints: false
+                        preserve_proto_field_names: true
+                  - name: envoy.router
+
+  clusters:
+    - name: grpc-backend-services
+      connect_timeout: 1.25s
+      type: logical_dns
+      lb_policy: round_robin
+      dns_lookup_family: V4_ONLY
+      http2_protocol_options: {}
+      hosts:
+        - socket_address:
+            address: localhost
+            port_value: 7000
diff --git a/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/generators b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/generators
new file mode 100644
index 0000000..3708bd9
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/generators
@@ -0,0 +1,3 @@
+protoc -I. src/main/proto/UserManagementService.proto  -Itarget/protoc-dependencies/e7d073a56b243f9050c875e9829e8969 -Itarget/protoc-dependencies/5f311595d3fcf1c213836eee4fc8c134  -Itarget/protoc-dependencies/3eb8afcacecd28a8c491b7d7a2a5a9cb  -Itarget/protoc-dependencies/c45363c9a53e872b1c7df0f960205860 -Itarget/protoc-dependencies/553743830f5a4c5dacb080d8dc7646f8 -Itarget/protoc-dependencies/0ee75fe78623861ec93de18b8cdf3c9e   --grpc-web_out=import_style=commonjs,mode=grpcwebtext:/Users/isururanawaka/Documents/Airavata_Repository/airavata-custos/custos-integration-services/user-management-service-parent/user-management-service
+
+protoc -I. src/main/proto/UserManagementService.proto  -Itarget/protoc-dependencies/e7d073a56b243f9050c875e9829e8969 -Itarget/protoc-dependencies/5f311595d3fcf1c213836eee4fc8c134  -Itarget/protoc-dependencies/3eb8afcacecd28a8c491b7d7a2a5a9cb  -Itarget/protoc-dependencies/c45363c9a53e872b1c7df0f960205860 -Itarget/protoc-dependencies/553743830f5a4c5dacb080d8dc7646f8 -Itarget/protoc-dependencies/0ee75fe78623861ec93de18b8cdf3c9e   --js_out=import_style=commonjs:/Users/isururanawaka/Documents/Airavata_Repository/airavata-custos/custos-integration-services/user-management-service-parent/user-management-service
\ No newline at end of file
diff --git a/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/user-management-service.pb b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/user-management-service.pb
new file mode 100644
index 0000000..baccaa2
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service-sidecar/src/main/resources/user-management-service.pb
Binary files differ
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/Dockerfile b/custos-integration-services/user-management-service-parent/user-management-service/Dockerfile
new file mode 100644
index 0000000..6457ff8
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/pom.xml b/custos-integration-services/user-management-service-parent/user-management-service/pom.xml
new file mode 100644
index 0000000..23c254d
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/pom.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>user-management-service-parent</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>user-management-service</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>iam-admin-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>credential-store-core-service-client-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-profile-core-service-client-stub</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-integration-services-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-sleuth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.zipkin.brave</groupId>
+            <artifactId>brave-instrumentation-grpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.api.grpc</groupId>
+            <artifactId>proto-google-common-protos</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.deviceinsight.helm</groupId>
+                <artifactId>helm-maven-plugin</artifactId>
+                <configuration>
+                    <skip>false</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/.helmignore b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/Chart.yaml b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..1cd4b75
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos user management service
+name: ${artifactId}
+version: ${project.version}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/NOTES.txt b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+  {{- range .paths }}
+  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+  {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+  echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+  echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+  echo "Visit http://127.0.0.1:8080 to use your application"
+  kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/_helpers.tpl b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/deployment.yaml b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..2fe140f
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,78 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helm.fullname" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  rollingUpdate:
+    maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+    maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "helm.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      annotations:
+        linkerd.io/inject: enabled
+      labels:
+        app.kubernetes.io/name: {{ include "helm.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+    {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "helm.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+            - name: grpc
+              containerPort: {{ .Values.service.grpcport }}
+              protocol: TCP
+          resources:
+              {{- toYaml .Values.resources | nindent 12 }}
+        - name: {{ .Chart.Name }}-envoy-proxy
+          securityContext:
+              {{- toYaml .Values.securityContext | nindent 12 }}
+          image: {{ .Values.proxy.repository }}:{{ .Values.proxy.tag }}
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: envoyhttp
+              containerPort: {{ .Values.proxy.port }}
+              protocol: TCP
+            - name: adminhttp
+              containerPort: {{ .Values.proxy.adminport }}
+              protocol: TCP
+          readinessProbe:
+            httpGet:
+              path: /actuator/health
+              port: {{ .Values.service.port }}
+              initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
+              periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+              successThreshold: {{ .Values.readinessProbe.successThreshold }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/ingress-grpc.yaml b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/ingress-grpc.yaml
new file mode 100644
index 0000000..c8f3487
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/ingress-grpc.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  annotations:
+    kubernetes.io/ingress.class: "nginx"
+    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
+    cert-manager.io/cluster-issuer: letsencrypt-production
+  name: ${artifactId}-ingress-grpc
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /org.apache.custos.user.management.service.UserManagementService(/|$)(.*)
+            backend:
+              serviceName: user-management-service
+              servicePort: grpc
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/ingress.yaml b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..fd24a57
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
+kind: Ingress
+metadata:
+  name: ${artifactId}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/rewrite-target: /user-management/$2
+    cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+  rules:
+    - host: custos.scigap.org
+      http:
+        paths:
+          - path: /user-management(/|$)(.*)
+            backend:
+              serviceName: user-management-service
+              servicePort: envoyhttp
+
+  tls:
+    - hosts:
+        - custos.scigap.org
+      secretName: tls-secret
\ No newline at end of file
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/service.yaml b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..878d1fb
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,24 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "helm.name" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+    - port: {{ .Values.service.grpcport }}
+      targetPort: grpc
+      protocol: TCP
+      name: grpc
+    - port: {{ .Values.proxy.port }}
+      targetPort: envoyhttp
+      protocol: TCP
+      name: envoyhttp
+  selector:
+    app.kubernetes.io/name: {{ include "helm.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/serviceaccount.yaml b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ template "helm.serviceAccountName" . }}
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/tests/test-connection.yaml b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helm.fullname" . }}-test-connection"
+  labels:
+{{ include "helm.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/values.yaml b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..a516b9c
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/helm/values.yaml
@@ -0,0 +1,84 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+  repository: apachecustos/${artifactId}
+  tag: ${project.version}
+  pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ${artifactId}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+  grpcport: 7000
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+proxy:
+   repository: apachecustos/user-management-service-sidecar
+   tag: 1.0-SNAPSHOT
+   port: 50000
+   adminport: 9901
+
+rollingUpdate:
+  maxSurge: 1
+  maxUnavailable: 25%
+
+readinessProbe:
+  initialDelaySeconds: 5
+  periodSeconds: 1
+  successThreshold: 1
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/UserManagementServiceInitializer.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/UserManagementServiceInitializer.java
new file mode 100644
index 0000000..42362d9
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/UserManagementServiceInitializer.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.management;
+
+import brave.Tracing;
+import brave.grpc.GrpcTracing;
+import io.grpc.ClientInterceptor;
+import io.grpc.ServerInterceptor;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
+import org.apache.custos.integration.services.commons.interceptors.LoggingInterceptor;
+import org.apache.custos.user.management.interceptors.ClientAuthInterceptorImpl;
+import org.apache.custos.user.management.interceptors.InputValidator;
+import org.apache.custos.user.management.interceptors.SuperTenantRestrictedOperationsInterceptorImpl;
+import org.apache.custos.user.management.interceptors.UserAuthInterceptorImpl;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+import java.util.Stack;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "org.apache.custos")
+public class UserManagementServiceInitializer {
+    public static void main(String[] args) {
+        SpringApplication.run(UserManagementServiceInitializer.class, args);
+    }
+
+    @Bean
+    public GrpcTracing grpcTracing(Tracing tracing) {
+        //   Tracing tracing1 =  Tracing.newBuilder().build();
+        return GrpcTracing.create(tracing);
+    }
+
+    //We also create a client-side interceptor and put that in the context, this interceptor can then be injected into gRPC clients and
+    //then applied to the managed channel.
+    @Bean
+    ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newClientInterceptor();
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
+        return grpcTracing.newServerInterceptor();
+    }
+
+    @Bean
+    public Stack<IntegrationServiceInterceptor> getInterceptorSet(InputValidator inputValidator,
+                                                                  ClientAuthInterceptorImpl authInterceptor,
+                                                                  UserAuthInterceptorImpl userAuthInterceptor,
+                                                                  SuperTenantRestrictedOperationsInterceptorImpl superTenantRestrictedOperationsInterceptor,
+                                                                  LoggingInterceptor loggingInterceptor) {
+        Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
+        interceptors.add(inputValidator);
+        interceptors.add(authInterceptor);
+        interceptors.add(userAuthInterceptor);
+        interceptors.add(superTenantRestrictedOperationsInterceptor);
+        interceptors.add(loggingInterceptor);
+
+
+        return interceptors;
+    }
+
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(Stack<IntegrationServiceInterceptor> integrationServiceInterceptors) {
+        return new ServiceInterceptor(integrationServiceInterceptors);
+    }
+}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/ClientAuthInterceptorImpl.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/ClientAuthInterceptorImpl.java
new file mode 100644
index 0000000..8abd0b1
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/ClientAuthInterceptorImpl.java
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.iam.service.FindUsersRequest;
+import org.apache.custos.iam.service.RegisterUserRequest;
+import org.apache.custos.iam.service.ResetUserPassword;
+import org.apache.custos.iam.service.UserSearchRequest;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.core.utils.Constants;
+import org.apache.custos.integration.services.commons.interceptors.MultiTenantAuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.user.management.service.UserProfileRequest;
+import org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate confidential client specific authorization.
+ * Methods which authenticates based only on client are implemented here.
+ */
+@Component
+public class ClientAuthInterceptorImpl extends MultiTenantAuthInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+    @Autowired
+    public ClientAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT reqT) {
+
+
+        if (method.equals("deleteUserProfile")) {
+            UserProfileRequest request = (UserProfileRequest) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            return (ReqT) ((UserProfileRequest) reqT).toBuilder()
+                    .setClientId(oauthId)
+                    .setClientSecret(oauthSec)
+                    .setTenantId(tenantId)
+                    .build();
+
+        } else if (method.equals("registerUser")) {
+
+            RegisterUserRequest request = (RegisterUserRequest) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            org.apache.custos.iam.service.RegisterUserRequest registerUserRequest =
+                    ((RegisterUserRequest) reqT).toBuilder()
+                            .setTenantId(tenantId)
+                            .setClientId(oauthId)
+                            .setClientSec(oauthSec)
+                            .build();
+
+            return (ReqT) registerUserRequest;
+        } else if (method.equals("enableUser") || method.equals("disableUser") ||
+                method.equals("isUserEnabled") || method.equals("isUsernameAvailable")) {
+            UserSearchRequest request = (UserSearchRequest) reqT;
+            AuthClaim claim = authorize(headers, request.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            UserSearchRequest info = ((UserSearchRequest) reqT)
+                    .toBuilder()
+                    .setClientId(oauthId)
+                    .setClientSec(oauthSec)
+                    .setTenantId(tenantId)
+                    .build();
+
+            return (ReqT) info;
+
+        } else if (method.equals("getUserProfile")) {
+
+            UserProfileRequest req = (UserProfileRequest) reqT;
+            AuthClaim claim = authorize(headers, req.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            UserProfileRequest request = ((UserProfileRequest) reqT)
+                    .toBuilder()
+                    .setTenantId(tenantId).build();
+
+            return (ReqT) request;
+        } else if (method.equals("getAllUserProfilesInTenant")) {
+            UserProfileRequest req = (UserProfileRequest) reqT;
+            AuthClaim claim = authorize(headers, req.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            UserProfileRequest request = ((UserProfileRequest) reqT)
+                    .toBuilder().setTenantId(tenantId).build();
+
+            return (ReqT) request;
+        } else if (method.equals("getUserProfileAuditTrails")) {
+            AuthClaim claim = authorize(headers);
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            GetUpdateAuditTrailRequest request = ((GetUpdateAuditTrailRequest) reqT)
+                    .toBuilder()
+                    .setTenantId(tenantId)
+                    .build();
+
+            return (ReqT) request;
+        } else if (method.equals("resetPassword")) {
+            ResetUserPassword req = (ResetUserPassword) reqT;
+            AuthClaim claim = authorize(headers, req.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+
+            ResetUserPassword request = ((ResetUserPassword) reqT)
+                    .toBuilder()
+                    .setClientId(oauthId)
+                    .setClientSec(oauthSec)
+                    .setTenantId(tenantId)
+                    .build();
+
+            return (ReqT) request;
+        } else if (method.equals("getUser")) {
+            UserSearchRequest req = (UserSearchRequest) reqT;
+
+            AuthClaim claim = authorize(headers, req.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+
+
+            UserSearchRequest request = ((UserSearchRequest) reqT)
+                    .toBuilder()
+                    .setClientId(oauthId)
+                    .setTenantId(tenantId)
+                    .setClientSec(oauthSec)
+                    .build();
+            return (ReqT) request;
+
+        } else if (method.equals("findUsers")) {
+            FindUsersRequest req = (FindUsersRequest) reqT;
+            AuthClaim claim = authorize(headers, req.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            FindUsersRequest request = ((FindUsersRequest) reqT)
+                    .toBuilder()
+                    .setClientId(oauthId)
+                    .setClientSec(oauthSec)
+                    .setTenantId(tenantId).build();
+
+
+            return (ReqT) request;
+        } else if (method.equals("updateUserProfile")) {
+
+            UserProfileRequest userProfileRequest = (UserProfileRequest) reqT;
+
+            AuthClaim claim = authorize(headers, userProfileRequest.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+
+            AuthToken token = getSAToken(claim.getIamAuthId(), claim.getIamAuthSecret(), claim.getTenantId());
+            if (token == null || token.getAccessToken() == null) {
+                throw new NotAuthorizedException("Request is not authorized SA token is invalid", null);
+            }
+
+            return (ReqT) ((UserProfileRequest) reqT).toBuilder()
+                    .setAccessToken(token.getAccessToken())
+                    .setTenantId(tenantId)
+                    .setClientId(oauthId)
+                    .setClientSecret(oauthSec)
+                    .setPerformedBy(Constants.SYSTEM)
+                    .build();
+
+        }
+        return reqT;
+    }
+
+}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/InputValidator.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/InputValidator.java
new file mode 100644
index 0000000..a5d46ab
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/InputValidator.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.management.interceptors;
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.grpc.Metadata;
+import org.apache.custos.integration.core.exceptions.MissingParameterException;
+import org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.user.management.service.LinkUserProfileRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class validates the  request input parameters
+ */
+@Component
+public class InputValidator implements IntegrationServiceInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(InputValidator.class);
+
+    /**
+     * Input parameter validater
+     *
+     * @param methodName
+     * @param body
+     * @return
+     */
+    private void validate(String methodName, Object body, Metadata headers) {
+
+        switch (methodName) {
+            case "linkUserProfile":
+                validateLinkUserProfile(methodName, body, headers);
+                break;
+            default:
+        }
+    }
+
+
+    private boolean validateLinkUserProfile(String methodName, Object body, Metadata headers) {
+        validationAuthorizationHeader(headers);
+        LinkUserProfileRequest request = ((LinkUserProfileRequest) body);
+
+        if (request.getPreviousUsername() == null || request.getPreviousUsername().equals("")) {
+            throw new MissingParameterException("Previous Username should not be null", null);
+        }
+        if (request.getCurrentUsername() == null || request.getCurrentUsername().equals("")) {
+            throw new MissingParameterException("Current username  should not be null", null);
+        }
+        if (request.getLinkingAttributesList().isEmpty()) {
+            throw new MissingParameterException("Linking attributes should not be empty", null);
+        }
+
+
+        return true;
+    }
+
+
+    private boolean validationAuthorizationHeader(Metadata headers) {
+        if (headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER)) == null
+                || headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)) == null) {
+            throw new MissingParameterException("authorization header not available", null);
+        }
+
+        return true;
+    }
+
+
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        validate(method, msg, headers);
+        return msg;
+    }
+}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/SuperTenantRestrictedOperationsInterceptorImpl.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/SuperTenantRestrictedOperationsInterceptorImpl.java
new file mode 100644
index 0000000..6f82546
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/SuperTenantRestrictedOperationsInterceptorImpl.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.iam.service.GetAllResources;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.services.commons.interceptors.AuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SuperTenantRestrictedOperationsInterceptorImpl extends AuthInterceptor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SuperTenantRestrictedOperationsInterceptorImpl.class);
+
+    private CredentialStoreServiceClient credentialStoreServiceClient;
+
+
+    public SuperTenantRestrictedOperationsInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient,
+                                                          TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+        this.credentialStoreServiceClient = credentialStoreServiceClient;
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+
+        if (method.equals("synchronizeUserDBs")) {
+            AuthClaim claim = null;
+            try {
+                claim = authorizeUsingUserToken(headers);
+            } catch (Exception ex) {
+                LOGGER.error(" Authorizing error " + ex.getMessage());
+                throw new NotAuthorizedException("Request is not authorized", ex);
+            }
+            if (claim == null || !claim.isSuperTenant() || !claim.isAdmin()) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+        }
+
+        return msg;
+    }
+
+
+}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/UserAuthInterceptorImpl.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/UserAuthInterceptorImpl.java
new file mode 100644
index 0000000..bb375cb
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/interceptors/UserAuthInterceptorImpl.java
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import org.apache.custos.integration.core.utils.Constants;
+import org.apache.custos.integration.services.commons.interceptors.MultiTenantAuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.apache.custos.user.management.service.LinkUserProfileRequest;
+import org.apache.custos.user.management.service.UserProfileRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Responsible for validate user specific authorization
+ * Methods authenticates users access tokens are implemented here
+ */
+@Component
+public class UserAuthInterceptorImpl extends MultiTenantAuthInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientAuthInterceptorImpl.class);
+
+    @Autowired
+    public UserAuthInterceptorImpl(CredentialStoreServiceClient credentialStoreServiceClient, TenantProfileClient tenantProfileClient, IdentityClient identityClient) {
+        super(credentialStoreServiceClient, tenantProfileClient, identityClient);
+    }
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+
+
+        if (method.equals("addUserAttributes")) {
+            AddUserAttributesRequest userAttributesRequest = (AddUserAttributesRequest) msg;
+            headers =  attachUserToken(headers, userAttributesRequest.getClientId());
+            AuthClaim claim = authorize(headers, userAttributesRequest.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+
+            long tenantId = claim.getTenantId();
+
+            AuthToken token = getSAToken(claim.getIamAuthId(), claim.getIamAuthSecret(), claim.getTenantId());
+            if (token == null || token.getAccessToken() == null) {
+                throw new NotAuthorizedException("Request is not authorized SA token is invalid", null);
+            }
+
+
+            return (ReqT) ((AddUserAttributesRequest) msg).toBuilder()
+                    .setClientId(oauthId)
+                    .setTenantId(tenantId)
+                    .setAccessToken(token.getAccessToken())
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+        } else if (method.equals("deleteUserAttributes")) {
+
+            DeleteUserAttributeRequest userAttributesRequest = (DeleteUserAttributeRequest) msg;
+            headers =  attachUserToken(headers, userAttributesRequest.getClientId());
+            AuthClaim claim = authorize(headers, userAttributesRequest.getClientId());
+
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+
+            long tenantId = claim.getTenantId();
+
+            AuthToken token = getSAToken(claim.getIamAuthId(), claim.getIamAuthSecret(), claim.getTenantId());
+            if (token == null || token.getAccessToken() == null) {
+                throw new NotAuthorizedException("Request is not authorized SA token is invalid", null);
+            }
+
+            return (ReqT) ((DeleteUserAttributeRequest) msg).toBuilder()
+                    .setClientId(oauthId)
+                    .setTenantId(tenantId)
+                    .setAccessToken(token.getAccessToken())
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+        } else if (method.equals("addRolesToUsers")) {
+
+            AddUserRolesRequest userAttributesRequest = (AddUserRolesRequest) msg;
+            headers =  attachUserToken(headers, userAttributesRequest.getClientId());
+            AuthClaim claim = authorize(headers, userAttributesRequest.getClientId());
+
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+
+            long tenantId = claim.getTenantId();
+
+            String userToken = getUserTokenFromUserTokenHeader(headers);
+
+            if (userToken == null || userToken.trim().equals("")) {
+                userToken = getToken(headers);
+            }
+
+
+            return (ReqT) ((AddUserRolesRequest) msg).toBuilder()
+                    .setClientId(oauthId)
+                    .setTenantId(tenantId)
+                    .setAccessToken(userToken)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+        } else if (method.equals("registerAndEnableUsers")) {
+
+            RegisterUsersRequest registerUsersRequest = (RegisterUsersRequest) msg;
+            headers =  attachUserToken(headers, registerUsersRequest.getClientId());
+            AuthClaim claim = authorize(headers, registerUsersRequest.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+            String userToken = getUserTokenFromUserTokenHeader(headers);
+
+            if (userToken == null || userToken.trim().equals("")) {
+                userToken = getToken(headers);
+            }
+
+            long tenantId = claim.getTenantId();
+            org.apache.custos.iam.service.RegisterUsersRequest registerUserRequest =
+                    ((RegisterUsersRequest) msg).toBuilder()
+                            .setTenantId(tenantId)
+                            .setClientId(oauthId)
+                            .setAccessToken(userToken)
+                            .setPerformedBy(claim.getPerformedBy())
+                            .build();
+            return (ReqT) registerUserRequest;
+        } else if (method.equals("deleteUserRoles")) {
+
+            DeleteUserRolesRequest deleteUserRolesRequest = (DeleteUserRolesRequest) msg;
+            headers =  attachUserToken(headers, deleteUserRolesRequest.getClientId());
+            AuthClaim claim = authorize(headers, deleteUserRolesRequest.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+            String userToken = getUserTokenFromUserTokenHeader(headers);
+
+            if (userToken == null || userToken.trim().equals("")) {
+                userToken = getToken(headers);
+            }
+
+            long tenantId = claim.getTenantId();
+            DeleteUserRolesRequest operationRequest = ((DeleteUserRolesRequest) msg)
+                    .toBuilder()
+                    .setClientId(oauthId)
+                    .setAccessToken(userToken)
+                    .setTenantId(tenantId)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+            return (ReqT) operationRequest;
+
+        }  else if (method.equals("deleteUser") || method.equals("grantAdminPrivileges") ||
+                method.equals("removeAdminPrivileges")) {
+
+            UserSearchRequest userSearchRequest = (UserSearchRequest) msg;
+            headers =  attachUserToken(headers, userSearchRequest.getClientId());
+            AuthClaim claim = authorize(headers, userSearchRequest.getClientId());
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            AuthToken token = getSAToken(claim.getIamAuthId(), claim.getIamAuthSecret(), claim.getTenantId());
+            if (token == null || token.getAccessToken() == null) {
+                throw new NotAuthorizedException("Request is not authorized SA token is invalid", null);
+            }
+
+
+            long tenantId = claim.getTenantId();
+            UserSearchRequest operationRequest = ((UserSearchRequest) msg)
+                    .toBuilder()
+                    .setClientId(oauthId)
+                    .setClientSec(oauthSec)
+                    .setTenantId(tenantId)
+                    .setAccessToken(token.getAccessToken())
+                    .setPerformedBy(Constants.SYSTEM)
+                    .build();
+
+            return (ReqT) operationRequest;
+
+        } else if (method.equals("linkUserProfile")) {
+            String token = getToken(headers);
+            AuthClaim claim = authorizeUsingUserToken(headers);
+
+            if (claim == null) {
+                throw new NotAuthorizedException("Request is not authorized", null);
+            }
+
+            String oauthId = claim.getIamAuthId();
+            String oauthSec = claim.getIamAuthSecret();
+
+            long tenantId = claim.getTenantId();
+            LinkUserProfileRequest operationRequest = ((LinkUserProfileRequest) msg)
+                    .toBuilder()
+                    .setIamClientId(oauthId)
+                    .setIamClientSecret(oauthSec)
+                    .setTenantId(tenantId)
+                    .setAccessToken(token)
+                    .setPerformedBy(claim.getPerformedBy())
+                    .build();
+
+            return (ReqT) operationRequest;
+
+        }
+
+        return msg;
+    }
+
+
+
+    private Metadata attachUserToken(Metadata headers, String clientId) {
+        if (clientId == null || clientId.trim().equals("")) {
+           String formattedUserToken =  getToken(headers);
+           headers.put(Metadata.Key.of(Constants.USER_TOKEN,Metadata.ASCII_STRING_MARSHALLER), formattedUserToken);
+           return headers;
+        }
+        return headers;
+    }
+
+
+}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/service/UserManagementService.java b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/service/UserManagementService.java
new file mode 100644
index 0000000..84b2fac
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/java/org/apache/custos/user/management/service/UserManagementService.java
@@ -0,0 +1,1366 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.custos.user.management.service;
+
+import io.grpc.Context;
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.iam.admin.client.IamAdminServiceClient;
+import org.apache.custos.iam.service.UserAttribute;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.identity.service.GetUserManagementSATokenRequest;
+import org.apache.custos.integration.core.utils.Constants;
+import org.apache.custos.user.profile.client.UserProfileClient;
+import org.apache.custos.user.profile.service.*;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Service class of User Management Service
+ */
+@GRpcService
+public class UserManagementService extends UserManagementServiceGrpc.UserManagementServiceImplBase {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserManagementService.class);
+
+
+    @Autowired
+    private UserProfileClient userProfileClient;
+
+    @Autowired
+    private IamAdminServiceClient iamAdminServiceClient;
+
+    @Autowired
+    private IdentityClient identityClient;
+
+
+    @Override
+    public void registerUser(RegisterUserRequest request, StreamObserver<RegisterUserResponse> responseObserver) {
+        try {
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+
+                org.apache.custos.iam.service.RegisterUserRequest registerUserRequest = request.
+                        toBuilder()
+                        .setAccessToken(token.getAccessToken())
+                        .build();
+
+                RegisterUserResponse registerUserResponse = iamAdminServiceClient.registerUser(registerUserRequest);
+
+                responseObserver.onNext(registerUserResponse);
+                responseObserver.onCompleted();
+
+            } else {
+                LOGGER.error("Cannot find service token");
+                responseObserver.onError(Status.CANCELLED.
+                        withDescription("Cannot find service token").asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while registering users,  " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("CredentialGenerationException")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+
+
+    }
+
+
+    @Override
+    public void registerAndEnableUsers(RegisterUsersRequest request, StreamObserver<RegisterUsersResponse> responseObserver) {
+        try {
+
+            RegisterUsersResponse registerUsersResponse = iamAdminServiceClient.
+                    registerAndEnableUsers(request);
+
+
+            if (request.getUsersList() != null && !request.getUsersList().isEmpty() &&
+                    registerUsersResponse.getAllUseresRegistered()) {
+                try {
+
+
+                    request.getUsersList().forEach(user -> {
+                        List<org.apache.custos.user.profile.service.UserAttribute> userAtrList = new ArrayList<>();
+                        if (user.getAttributesList() != null && !user.getAttributesList().isEmpty()) {
+
+                            user.getAttributesList().forEach(atr -> {
+                                org.apache.custos.user.profile.service.UserAttribute userAttribute =
+                                        org.apache.custos.user.profile.service.UserAttribute
+                                                .newBuilder()
+                                                .setKey(atr.getKey())
+                                                .addAllValue(atr.getValuesList())
+                                                .build();
+
+                                userAtrList.add(userAttribute);
+                            });
+                        }
+
+
+                        UserProfile profile = UserProfile.newBuilder()
+                                .setFirstName(user.getFirstName())
+                                .setLastName(user.getLastName())
+                                .setEmail(user.getEmail())
+                                .setStatus(UserStatus.valueOf("ACTIVE"))
+                                .addAllAttributes(userAtrList)
+                                .addAllRealmRoles(user.getRealmRolesList())
+                                .addAllClientRoles(user.getClientRolesList())
+                                .setUsername(user.getUsername().toLowerCase())
+                                .build();
+                        org.apache.custos.user.profile.service.UserProfileRequest profileRequest =
+                                org.apache.custos.user.profile.service.UserProfileRequest.newBuilder()
+                                        .setProfile(profile)
+                                        .setTenantId(request.getTenantId())
+                                        .build();
+
+                        userProfileClient.createUserProfile(profileRequest);
+
+
+                    });
+                } catch (Exception ex) {
+
+                    request.getUsersList().forEach(user -> {
+
+                        UserSearchMetadata metadata = UserSearchMetadata
+                                .newBuilder()
+                                .setUsername(user.getUsername())
+                                .build();
+                        UserSearchRequest searchRequest = UserSearchRequest
+                                .newBuilder()
+                                .setTenantId(request.getTenantId())
+                                .setClientId(request.getClientId())
+                                .setAccessToken(request.getAccessToken())
+                                .setUser(metadata)
+                                .build();
+                        iamAdminServiceClient.deleteUser(searchRequest);
+
+                    });
+
+                }
+
+            }
+
+            responseObserver.onNext(registerUsersResponse);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while registering and enabling  users,  " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+
+    }
+
+
+    @Override
+    public void addUserAttributes(AddUserAttributesRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            OperationStatus status = iamAdminServiceClient.addUserAttributes(request);
+
+
+            for (String user : request.getUsersList()) {
+
+                UserSearchMetadata metadata = UserSearchMetadata
+                        .newBuilder()
+                        .setUsername(user).build();
+
+                UserSearchRequest searchRequest = UserSearchRequest
+                        .newBuilder()
+                        .setClientId(request.getClientId())
+                        .setTenantId(request.getTenantId())
+                        .setAccessToken(request.getAccessToken())
+                        .setUser(metadata)
+                        .build();
+
+                UserRepresentation representation = iamAdminServiceClient.getUser(searchRequest);
+
+
+                if (representation != null) {
+
+                    UserProfile profile = this.convertToProfile(representation);
+
+                    org.apache.custos.user.profile.service.UserProfileRequest req =
+                            org.apache.custos.user.profile.service.UserProfileRequest
+                                    .newBuilder()
+                                    .setTenantId(request.getTenantId())
+                                    .setProfile(profile)
+                                    .build();
+
+
+                    UserProfile existingProfile = userProfileClient.getUser(req);
+
+                    if (existingProfile == null || existingProfile.getUsername().trim().equals("")) {
+                        userProfileClient.createUserProfile(req);
+                    } else {
+
+                        userProfileClient.updateUserProfile(req);
+                    }
+
+
+                }
+
+            }
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while adding user attributes, " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void deleteUserAttributes(DeleteUserAttributeRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            OperationStatus status = iamAdminServiceClient.deleteUserAttributes(request);
+
+
+            for (String user : request.getUsersList()) {
+
+                UserSearchMetadata metadata = UserSearchMetadata
+                        .newBuilder()
+                        .setUsername(user).build();
+
+                UserSearchRequest searchRequest = UserSearchRequest
+                        .newBuilder()
+                        .setClientId(request.getClientId())
+                        .setTenantId(request.getTenantId())
+                        .setAccessToken(request.getAccessToken())
+                        .setUser(metadata)
+                        .build();
+
+                UserRepresentation representation = iamAdminServiceClient.getUser(searchRequest);
+
+
+                if (representation != null) {
+
+                    UserProfile profile = this.convertToProfile(representation);
+
+                    org.apache.custos.user.profile.service.UserProfileRequest req =
+                            org.apache.custos.user.profile.service.UserProfileRequest
+                                    .newBuilder()
+                                    .setTenantId(request.getTenantId())
+                                    .setProfile(profile)
+                                    .build();
+
+
+                    userProfileClient.updateUserProfile(req);
+
+
+                }
+
+            }
+            responseObserver.onNext(status);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting user attributes " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void enableUser(UserSearchRequest request, StreamObserver<UserRepresentation> responseObserver) {
+        try {
+
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+
+                request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+
+                UserRepresentation user = iamAdminServiceClient.enableUser(request);
+
+                if (user != null) {
+
+                    UserProfile profile = this.convertToProfile(user);
+
+                    org.apache.custos.user.profile.service.UserProfileRequest profileRequest =
+                            org.apache.custos.user.profile.service.UserProfileRequest.newBuilder()
+                                    .setProfile(profile)
+                                    .setTenantId(request.getTenantId())
+                                    .build();
+
+                    UserProfile exProfile = userProfileClient.getUser(profileRequest);
+
+                    if (exProfile.getUsername().equals("")) {
+                        userProfileClient.createUserProfile(profileRequest);
+                    } else {
+                        userProfileClient.updateUserProfile(profileRequest);
+                    }
+
+
+                    responseObserver.onNext(user);
+                    responseObserver.onCompleted();
+
+
+                } else {
+                    String msg = "User enabling failed at IDP server";
+                    LOGGER.error(msg);
+                    responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
+
+                }
+            } else {
+                LOGGER.error("Cannot find service token");
+                responseObserver.onError(Status.CANCELLED.
+                        withDescription("Cannot find service token").asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while enabling user,  " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void disableUser(UserSearchRequest request, StreamObserver<UserRepresentation> responseObserver) {
+        try {
+
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+
+                request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+
+                UserRepresentation user = iamAdminServiceClient.disableUser(request);
+
+                if (user != null) {
+
+                    UserProfile profile = this.convertToProfile(user);
+
+                    org.apache.custos.user.profile.service.UserProfileRequest profileRequest =
+                            org.apache.custos.user.profile.service.UserProfileRequest.newBuilder()
+                                    .setProfile(profile)
+                                    .setTenantId(request.getTenantId())
+                                    .build();
+
+                    UserProfile exProfile = userProfileClient.getUser(profileRequest);
+
+                    if (exProfile.getUsername().equals("")) {
+                        userProfileClient.createUserProfile(profileRequest);
+                    } else {
+                        userProfileClient.updateUserProfile(profileRequest);
+                    }
+
+
+                    responseObserver.onNext(user);
+                    responseObserver.onCompleted();
+
+
+                } else {
+                    String msg = "User enabling failed at IDP server";
+                    LOGGER.error(msg);
+                    responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
+
+                }
+            } else {
+                LOGGER.error("Cannot find service token");
+                responseObserver.onError(Status.CANCELLED.
+                        withDescription("Cannot find service token").asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while disabling user, " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void deleteUser(UserSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            UserProfile profileReq = UserProfile.newBuilder().setUsername(request.getUser().getUsername().toLowerCase()).build();
+
+
+            org.apache.custos.user.profile.service.UserProfileRequest req =
+                    org.apache.custos.user.profile.service.UserProfileRequest
+                            .newBuilder()
+                            .setTenantId(request.getTenantId())
+                            .setProfile(profileReq)
+                            .build();
+
+            UserProfile profile = userProfileClient.getUser(req);
+
+            if (profile != null && !profile.getUsername().trim().equals("")) {
+
+
+                UserProfile deletedProfile = userProfileClient.deleteUser(req);
+
+                if (deletedProfile != null) {
+
+                    OperationStatus response = iamAdminServiceClient.deleteUser(request);
+
+                    responseObserver.onNext(response);
+                    responseObserver.onCompleted();
+
+
+                } else {
+                    String msg = "User profile deletion failed for " + request.getUser().getUsername();
+                    LOGGER.error(msg);
+                    responseObserver.onError(Status.CANCELLED.withDescription(msg).asRuntimeException());
+                }
+
+            } else {
+                OperationStatus response = iamAdminServiceClient.deleteUser(request);
+
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while  deleting user " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void getUser(UserSearchRequest request, StreamObserver<UserRepresentation> responseObserver) {
+        try {
+
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+
+                request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+
+                UserRepresentation user = iamAdminServiceClient.getUser(request);
+
+                responseObserver.onNext(user);
+                responseObserver.onCompleted();
+            } else {
+                LOGGER.error("Cannot find service token");
+                responseObserver.onError(Status.CANCELLED.
+                        withDescription("Cannot find service token").asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while fetching user, " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else if (ex.getMessage().contains("NOT_FOUND")) {
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void findUsers(FindUsersRequest request, StreamObserver<FindUsersResponse> responseObserver) {
+        try {
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+
+                request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+                FindUsersResponse user = iamAdminServiceClient.getUsers(request);
+                responseObserver.onNext(user);
+                responseObserver.onCompleted();
+            } else {
+                LOGGER.error("Cannot find service token");
+                responseObserver.onError(Status.CANCELLED.
+                        withDescription("Cannot find service token").asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling users, " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+    @Override
+    public void resetPassword(ResetUserPassword request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+
+                request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+
+                OperationStatus response = iamAdminServiceClient.resetPassword(request);
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            } else {
+                LOGGER.error("Cannot find service token");
+                responseObserver.onError(Status.CANCELLED.
+                        withDescription("Cannot find service token").asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred  while resetting password " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void addRolesToUsers(AddUserRolesRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            OperationStatus response = iamAdminServiceClient.addRolesToUsers(request);
+
+            for (String user : request.getUsernamesList()) {
+
+                UserSearchMetadata metadata = UserSearchMetadata
+                        .newBuilder()
+                        .setUsername(user).build();
+
+                UserSearchRequest searchRequest = UserSearchRequest
+                        .newBuilder()
+                        .setClientId(request.getClientId())
+                        .setTenantId(request.getTenantId())
+                        .setAccessToken(request.getAccessToken())
+                        .setUser(metadata)
+                        .build();
+
+                UserRepresentation representation = iamAdminServiceClient.getUser(searchRequest);
+
+
+                if (representation != null) {
+
+                    UserProfile profile = this.convertToProfile(representation);
+
+                    org.apache.custos.user.profile.service.UserProfileRequest req =
+                            org.apache.custos.user.profile.service.UserProfileRequest
+                                    .newBuilder()
+                                    .setTenantId(request.getTenantId())
+                                    .setProfile(profile)
+                                    .build();
+
+
+                    UserProfile exsistingProfile = userProfileClient.getUser(req);
+
+                    if (exsistingProfile == null || exsistingProfile.getUsername().trim().equals("")) {
+                        userProfileClient.createUserProfile(req);
+                    } else {
+
+                        userProfileClient.updateUserProfile(req);
+                    }
+                }
+
+            }
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while adding roles to users, " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void deleteUserRoles(DeleteUserRolesRequest
+                                        request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            OperationStatus response = iamAdminServiceClient.deleteUserRoles(request);
+
+
+            UserSearchMetadata metadata = UserSearchMetadata
+                    .newBuilder()
+                    .setUsername(request.getUsername()).build();
+
+            UserSearchRequest searchRequest = UserSearchRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setTenantId(request.getTenantId())
+                    .setAccessToken(request.getAccessToken())
+                    .setUser(metadata)
+                    .build();
+
+            UserRepresentation representation = iamAdminServiceClient.getUser(searchRequest);
+
+
+            if (representation != null) {
+
+                UserProfile profile = this.convertToProfile(representation);
+
+                org.apache.custos.user.profile.service.UserProfileRequest req =
+                        org.apache.custos.user.profile.service.UserProfileRequest
+                                .newBuilder()
+                                .setTenantId(request.getTenantId())
+                                .setProfile(profile)
+                                .build();
+
+
+                userProfileClient.updateUserProfile(req);
+
+
+            }
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (
+                Exception ex) {
+            String msg = "Error occurred while delete user roles,  " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+
+    }
+
+    @Override
+    public void isUserEnabled(UserSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+                request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+                OperationStatus response = iamAdminServiceClient.isUserEnabled(request);
+
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            } else {
+
+                LOGGER.error("Cannot find service token");
+                responseObserver.onError(Status.CANCELLED.
+                        withDescription("Cannot find service token").asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while enabling user " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void isUsernameAvailable(UserSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getClientId())
+                    .setClientSecret(request.getClientSec())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+                request = request.toBuilder().setAccessToken(token.getAccessToken()).build();
+                OperationStatus response = iamAdminServiceClient.isUsernameAvailable(request);
+
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            } else {
+
+                LOGGER.error("Cannot find service token");
+                responseObserver.onError(Status.CANCELLED.
+                        withDescription("Cannot find service token").asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while checking username, " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void updateUserProfile(UserProfileRequest request, StreamObserver<UserProfile> responseObserver) {
+        try {
+            LOGGER.debug("Request received to updateUserProfile for " + request.getUserProfile().getUsername() +
+                    " in " + request.getTenantId());
+
+            UserSearchMetadata metadata = UserSearchMetadata
+                    .newBuilder()
+                    .setUsername(request.getUserProfile().getUsername()).build();
+
+            UserSearchRequest info = UserSearchRequest
+                    .newBuilder()
+                    .setAccessToken(request.getAccessToken())
+                    .setTenantId(request.getTenantId())
+                    .setUser(metadata)
+                    .build();
+
+            CheckingResponse response = iamAdminServiceClient.isUserExist(info);
+
+
+            if (!response.getIsExist()) {
+                String msg = "User not found with username " + request.getUserProfile().getUsername();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.
+                        withDescription(msg).asRuntimeException());
+            }
+
+            UserRepresentation userRepresentation = iamAdminServiceClient.getUser(info);
+
+            userRepresentation = userRepresentation
+                    .toBuilder()
+                    .setFirstName(request.getUserProfile().getFirstName())
+                    .setLastName(request.getUserProfile().getLastName())
+                    .setEmail(request.getUserProfile().getEmail())
+                    .build();
+
+            UpdateUserProfileRequest updateUserProfileRequest = UpdateUserProfileRequest
+                    .newBuilder()
+                    .setUser(userRepresentation)
+                    .setAccessToken(request.getAccessToken())
+                    .setTenantId(request.getTenantId())
+                    .build();
+
+            OperationStatus operationStatus = iamAdminServiceClient.updateUserProfile(updateUserProfileRequest);
+
+            if (operationStatus != null && operationStatus.getStatus()) {
+                try {
+                    org.apache.custos.user.profile.service.UserProfileRequest userProfileRequest =
+                            org.apache.custos.user.profile.service.UserProfileRequest.
+                                    newBuilder()
+                                    .setProfile(request.getUserProfile())
+                                    .setTenantId(request.getTenantId())
+                                    .build();
+
+                    UserProfile profile = userProfileClient.getUser(userProfileRequest);
+
+                    if (profile != null && !profile.getUsername().equals("")) {
+                        profile = profile.toBuilder()
+                                .setEmail(request.getUserProfile().getEmail())
+                                .setFirstName(request.getUserProfile().getFirstName())
+                                .setLastName(request.getUserProfile().getLastName())
+                                .setUsername(request.getUserProfile().getUsername())
+                                .build();
+                        userProfileRequest = userProfileRequest.toBuilder().setProfile(profile).build();
+                        userProfileClient.
+                                updateUserProfile(userProfileRequest);
+                        responseObserver.onNext(profile);
+                        responseObserver.onCompleted();
+
+                    } else {
+                        UserProfile userProfile = UserProfile.newBuilder()
+                                .setEmail(request.getUserProfile().getEmail())
+                                .setFirstName(request.getUserProfile().getFirstName())
+                                .setLastName(request.getUserProfile().getLastName())
+                                .setUsername(request.getUserProfile().getUsername())
+                                .build();
+                        userProfileRequest = userProfileRequest.toBuilder().setProfile(userProfile).build();
+                        userProfileClient.createUserProfile(userProfileRequest);
+                        responseObserver.onNext(profile);
+                        responseObserver.onCompleted();
+                    }
+
+                } catch (Exception ex) {
+                    String msg = "Error occurred while saving user profile in local DB, " +
+                            "rolling back IAM service" + ex.getMessage();
+                    LOGGER.error(msg);
+                    UpdateUserProfileRequest rollingRequest = UpdateUserProfileRequest
+                            .newBuilder()
+                            .setUser(userRepresentation)
+                            .setAccessToken(request.getAccessToken())
+                            .setTenantId(request.getTenantId())
+                            .build();
+                    iamAdminServiceClient.updateUserProfile(rollingRequest);
+                    responseObserver.onError(Status.CANCELLED.
+                            withDescription(msg).asRuntimeException());
+                }
+            } else {
+                String msg = "Cannot update user profile in keycloak for user  " + request.getUserProfile().getUsername();
+                LOGGER.error(msg);
+                responseObserver.onError(Status.INTERNAL.
+                        withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while updating user profile " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void deleteUserProfile(UserProfileRequest request, StreamObserver<UserProfile> responseObserver) {
+        try {
+            LOGGER.debug("Request received to deleteUserProfile " + request.getUserProfile().getUsername() +
+                    " at" + request.getTenantId());
+
+            UserSearchMetadata metadata = UserSearchMetadata
+                    .newBuilder()
+                    .setUsername(request.getUserProfile().getUsername()).build();
+
+            UserSearchRequest info = UserSearchRequest
+                    .newBuilder()
+                    .setAccessToken(request.getAccessToken())
+                    .setTenantId(request.getTenantId())
+                    .setUser(metadata)
+                    .build();
+
+
+            org.apache.custos.user.profile.service.UserProfileRequest userProfileRequest =
+
+                    org.apache.custos.user.profile.service.UserProfileRequest
+                            .newBuilder()
+                            .setProfile(request.getUserProfile())
+                            .setTenantId(request.getTenantId())
+                            .build();
+            UserProfile userProfile = userProfileClient.deleteUser(userProfileRequest);
+
+            responseObserver.onNext(userProfile);
+            responseObserver.onCompleted();
+
+            iamAdminServiceClient.deleteUser(info);
+
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while deleting user profile " + ex.getMessage();
+            LOGGER.error(msg);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void getUserProfile(UserProfileRequest request, StreamObserver<UserProfile> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getUserProfile " + request.getUserProfile().getUsername() +
+                    " at" + request.getTenantId());
+
+            org.apache.custos.user.profile.service.UserProfileRequest userProfileRequest =
+
+                    org.apache.custos.user.profile.service.UserProfileRequest
+                            .newBuilder()
+                            .setProfile(request.getUserProfile())
+                            .setTenantId(request.getTenantId())
+                            .build();
+
+            UserProfile userProfile = userProfileClient.getUser(userProfileRequest);
+
+            responseObserver.onNext(userProfile);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling  user profile " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void getAllUserProfilesInTenant(UserProfileRequest
+                                                   request, StreamObserver<GetAllUserProfilesResponse> responseObserver) {
+        try {
+            LOGGER.debug("Request received to getAllUserProfilesInTenant " + request.getTenantId() +
+                    " at" + request.getTenantId());
+
+            org.apache.custos.user.profile.service.UserProfileRequest userProfileRequest =
+
+                    org.apache.custos.user.profile.service.UserProfileRequest
+                            .newBuilder()
+                            .setProfile(request.getUserProfile())
+                            .setTenantId(request.getTenantId())
+                            .build();
+
+
+            if (request.getUserProfile().getAttributesList() == null || request.getUserProfile().getAttributesList().isEmpty()) {
+                GetAllUserProfilesResponse response = userProfileClient.getAllUserProfilesInTenant(userProfileRequest);
+
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            } else {
+                GetAllUserProfilesResponse response = userProfileClient.findUserProfilesByUserAttributes(userProfileRequest);
+
+                responseObserver.onNext(response);
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling  all  user profiles in tenant " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void getUserProfileAuditTrails(GetUpdateAuditTrailRequest
+                                                  request, StreamObserver<GetUpdateAuditTrailResponse> responseObserver) {
+        try {
+
+            LOGGER.debug("Request received to getUserProfileAuditTrails " + request.getUsername() +
+                    " at" + request.getTenantId());
+
+            GetUpdateAuditTrailResponse response = userProfileClient.getUserProfileUpdateAuditTrail(request);
+
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while pulling user profile audit trails " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void linkUserProfile(LinkUserProfileRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+            LOGGER.debug("Request received to linkUserProfile   at " + request.getTenantId());
+
+            GetUserManagementSATokenRequest userManagementSATokenRequest = GetUserManagementSATokenRequest
+                    .newBuilder()
+                    .setClientId(request.getIamClientId())
+                    .setClientSecret(request.getIamClientSecret())
+                    .setTenantId(request.getTenantId())
+                    .build();
+            AuthToken token = identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+            if (token != null && token.getAccessToken() != null) {
+
+
+                UserSearchMetadata metadata = UserSearchMetadata
+                        .newBuilder()
+                        .setUsername(request.getCurrentUsername()).build();
+
+                UserSearchRequest searchRequest = UserSearchRequest
+                        .newBuilder()
+                        .setClientId(request.getIamClientId())
+                        .setTenantId(request.getTenantId())
+                        .setAccessToken(token.getAccessToken())
+                        .setUser(metadata)
+                        .build();
+
+
+                UserRepresentation userTobeLinked = iamAdminServiceClient.getUser(searchRequest);
+
+
+                if (userTobeLinked != null && !userTobeLinked.getUsername().equals("")) {
+
+                    UserSearchMetadata exMetadata = UserSearchMetadata
+                            .newBuilder().setUsername(request.getPreviousUsername()).build();
+
+                    UserSearchRequest exSearchRequest = UserSearchRequest
+                            .newBuilder()
+                            .setClientId(request.getIamClientId())
+                            .setTenantId(request.getTenantId())
+                            .setAccessToken(token.getAccessToken())
+                            .setUser(exMetadata)
+                            .build();
+
+                    UserRepresentation exRep = iamAdminServiceClient.getUser(exSearchRequest);
+
+                    if (exRep != null && !exRep.getUsername().equals("")) {
+
+                        boolean profileUpdate = false;
+
+                        List<UserAttribute> userAttributeList = new ArrayList<>();
+
+                        for (String attribute : request.getLinkingAttributesList()) {
+
+                            if ("name".equals(attribute)) {
+                                profileUpdate = true;
+                                userTobeLinked = userTobeLinked.toBuilder()
+                                        .setFirstName(exRep.getFirstName())
+                                        .setLastName(exRep.getLastName())
+                                        .build();
+
+                            } else if (("email").equals(attribute)) {
+                                profileUpdate = true;
+                                userTobeLinked = userTobeLinked.toBuilder().setEmail(exRep.getEmail()).build();
+
+                            } else {
+                                List<UserAttribute> userAttributes = exRep.getAttributesList().stream().
+                                        filter(atr -> atr.getKey().equals(attribute)).collect(Collectors.toList());
+
+                                if (!userAttributes.isEmpty()) {
+                                    UserAttribute userAttribute = userAttributes.get(0);
+                                    userAttributeList.add(userAttribute);
+                                }
+                            }
+                        }
+
+                        if (profileUpdate) {
+                            UpdateUserProfileRequest updateUserProfileRequest = UpdateUserProfileRequest
+                                    .newBuilder()
+                                    .setUser(userTobeLinked)
+                                    .setAccessToken(token.getAccessToken())
+                                    .setTenantId(request.getTenantId())
+                                    .build();
+                            iamAdminServiceClient.updateUserProfile(updateUserProfileRequest);
+                        }
+
+                        if (!userAttributeList.isEmpty()) {
+
+                            AddUserAttributesRequest addUserAttributesRequest = AddUserAttributesRequest
+                                    .newBuilder()
+                                    .addUsers(request.getCurrentUsername())
+                                    .addAllAttributes(userAttributeList)
+                                    .setTenantId(request.getTenantId())
+                                    .setAccessToken(token.getAccessToken())
+                                    .setClientId(request.getIamClientId())
+                                    .setPerformedBy(request.getPerformedBy())
+                                    .build();
+                            iamAdminServiceClient.addUserAttributes(addUserAttributesRequest);
+
+                        }
+
+
+                        UserRepresentation updatedUser = iamAdminServiceClient.getUser(searchRequest);
+
+                        if (updatedUser != null) {
+
+                            UserProfile profile = this.convertToProfile(updatedUser);
+
+                            org.apache.custos.user.profile.service.UserProfileRequest req =
+                                    org.apache.custos.user.profile.service.UserProfileRequest
+                                            .newBuilder()
+                                            .setTenantId(request.getTenantId())
+                                            .setProfile(profile)
+                                            .build();
+
+                            UserProfile exsistingProfile = userProfileClient.getUser(req);
+
+                            if (exsistingProfile == null || exsistingProfile.getUsername().equals("")) {
+                                userProfileClient.createUserProfile(req);
+                            } else {
+                                userProfileClient.updateUserProfile(req);
+                            }
+                        }
+
+                        CheckingResponse response = CheckingResponse.newBuilder().setIsExist(true).build();
+                        OperationStatus status = OperationStatus.newBuilder().setStatus(response.getIsExist()).build();
+                        responseObserver.onNext(status);
+                        responseObserver.onCompleted();
+
+                    } else {
+                        String msg = "Cannot found existing user ";
+                        LOGGER.error(msg);
+                        responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+                    }
+
+                }
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while linking user profile in tenant " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            if (ex.getMessage().contains("UNAUTHENTICATED")) {
+                responseObserver.onError(io.grpc.Status.UNAUTHENTICATED.withDescription(msg).asRuntimeException());
+            } else {
+                responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+        }
+    }
+
+
+    @Override
+    public void grantAdminPrivileges(UserSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            LOGGER.debug("Request received to grantAdminPrivileges " + request.getUser().getUsername() +
+                    " at" + request.getTenantId());
+
+            iamAdminServiceClient.grantAdminPrivilege(request);
+
+            UserRepresentation representation = iamAdminServiceClient.getUser(request);
+
+            if (representation != null) {
+
+                UserProfile profile = convertToProfile(representation);
+
+                org.apache.custos.user.profile.service.UserProfileRequest profileRequest = org.apache.custos.user.profile.service.UserProfileRequest
+                        .newBuilder()
+                        .setTenantId(request.getTenantId())
+                        .setPerformedBy(request.getPerformedBy())
+                        .setProfile(profile)
+                        .build();
+
+
+                UserProfile exProfile = userProfileClient.getUser(profileRequest);
+
+                if (exProfile == null || exProfile.getUsername().equals("")) {
+
+                    userProfileClient.createUserProfile(profileRequest);
+                } else {
+                    userProfileClient.updateUserProfile(profileRequest);
+
+                }
+
+                OperationStatus status = OperationStatus.newBuilder().setStatus(true).build();
+
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+            } else {
+                String msg = "User  not found";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while puling user profile audit trails " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeAdminPrivileges(UserSearchRequest request, StreamObserver<OperationStatus> responseObserver) {
+
+        try {
+            LOGGER.debug("Request received to removeAdminPrivileges " + request.getUser().getUsername() +
+                    " at" + request.getTenantId());
+
+            iamAdminServiceClient.removeAdminPrivilege(request);
+
+            UserRepresentation representation = iamAdminServiceClient.getUser(request);
+
+            if (representation != null) {
+
+                UserProfile profile = convertToProfile(representation);
+
+                org.apache.custos.user.profile.service.UserProfileRequest profileRequest = org.apache.custos.user.profile.service.UserProfileRequest
+                        .newBuilder()
+                        .setTenantId(request.getTenantId())
+                        .setPerformedBy(request.getPerformedBy())
+                        .setProfile(profile)
+                        .build();
+
+                UserProfile exProfile = userProfileClient.getUser(profileRequest);
+
+                if (exProfile == null || exProfile.getUsername().equals("")) {
+                    userProfileClient.createUserProfile(profileRequest);
+                } else {
+                    userProfileClient.updateUserProfile(profileRequest);
+                }
+
+                OperationStatus status = OperationStatus.newBuilder().setStatus(true).build();
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+            } else {
+                String msg = "User  not found";
+                LOGGER.error(msg);
+                responseObserver.onError(Status.NOT_FOUND.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            String msg = "Error occurred while  removing admin privileges " + ex.getMessage();
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+
+        }
+    }
+
+
+    @Override
+    public void synchronizeUserDBs(SynchronizeUserDBRequest request, StreamObserver<OperationStatus> responseObserver) {
+        try {
+
+            Context ctx = Context.current().fork();
+            ctx.run(() -> {
+                GetAllResources resources = GetAllResources
+                        .newBuilder()
+                        .setClientId(request.getClientId())
+                        .setTenantId(request.getTenantId())
+                        .setResourceType(ResourceTypes.USER)
+                        .build();
+                GetAllResourcesResponse response = iamAdminServiceClient.getAllResources(resources);
+
+                if (response != null && response.getUsersList() != null && !response.getUsersList().isEmpty()) {
+
+                    for (org.apache.custos.iam.service.UserRepresentation userRepresentation : response.getUsersList()) {
+
+                        LOGGER.info("User Name " + userRepresentation.getUsername());
+                        UserProfile profile = convertToProfile(userRepresentation);
+
+                        org.apache.custos.user.profile.service.UserProfileRequest profileRequest = org.apache.custos.user.profile.service.UserProfileRequest
+                                .newBuilder()
+                                .setTenantId(request.getTenantId())
+                                .setPerformedBy(Constants.SYSTEM)
+                                .setProfile(profile)
+                                .build();
+
+                        UserProfile exProfile = userProfileClient.getUser(profileRequest);
+
+                        if (exProfile == null || exProfile.getUsername().equals("")) {
+                            userProfileClient.createUserProfile(profileRequest);
+                        } else {
+                            userProfileClient.updateUserProfile(profileRequest);
+                        }
+                    }
+                } else {
+                    LOGGER.info("Empty");
+                }
+
+                OperationStatus status = OperationStatus.newBuilder().setStatus(true).build();
+
+                responseObserver.onNext(status);
+                responseObserver.onCompleted();
+            });
+        } catch (Exception ex) {
+            String msg = "Error occurred at synchronizeAgentDBs " + ex.getMessage();
+            LOGGER.error(msg, ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+    private UserProfile convertToProfile(UserRepresentation representation) {
+        UserProfile.Builder profileBuilder = UserProfile.newBuilder();
+
+
+        if (representation.getRealmRolesCount() > 0) {
+            profileBuilder.addAllRealmRoles(representation.getRealmRolesList());
+
+        }
+
+        if (representation.getClientRolesCount() > 0) {
+            profileBuilder.addAllClientRoles(representation.getClientRolesList());
+
+        }
+
+        if (representation.getAttributesCount() > 0) {
+            List<UserAttribute> attributeList = representation.getAttributesList();
+
+            List<org.apache.custos.user.profile.service.UserAttribute> userAtrList = new ArrayList<>();
+            attributeList.forEach(atr -> {
+                org.apache.custos.user.profile.service.UserAttribute userAttribute =
+                        org.apache.custos.user.profile.service.UserAttribute
+                                .newBuilder()
+                                .setKey(atr.getKey())
+                                .addAllValue(atr.getValuesList())
+                                .build();
+
+                userAtrList.add(userAttribute);
+            });
+            profileBuilder.addAllAttributes(userAtrList);
+
+
+        }
+
+        profileBuilder.setUsername(representation.getUsername().toLowerCase());
+        profileBuilder.setFirstName(representation.getFirstName());
+        profileBuilder.setLastName(representation.getLastName());
+        profileBuilder.setEmail(representation.getEmail());
+
+        return profileBuilder.build();
+
+    }
+
+
+}
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService.proto b/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService.proto
new file mode 100644
index 0000000..f6f73cb
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService.proto
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.user.management.service;
+
+import "google/api/annotations.proto";
+import "UserProfileService.proto";
+import "IamAdminService.proto";
+
+
+message UserProfileRequest {
+    org.apache.custos.user.profile.service.UserProfile user_profile = 1;
+    string clientId = 2;
+    int64 tenantId = 3;
+    string accessToken = 4;
+    string clientSecret = 5;
+    string performedBy = 6;
+}
+
+message GetUserRequest {
+    string username = 1;
+    org.apache.custos.iam.service.UserSearchRequest userSearchRequest = 2;
+}
+
+message GetUsersRequest {
+    int64 tenantId = 1;
+    string email = 2;
+    string username = 3;
+    int32 offset = 4;
+    int32 limit = 5;
+    string search = 6;
+    string iamClientId = 7;
+    string iamClientSecret = 8;
+}
+
+message ResetPassword {
+    int64 tenantId = 1;
+    string accessToken = 2;
+    string username = 3;
+    string password = 4;
+    string iamClientId = 5;
+    string iamClientSecret = 6;
+}
+
+message ResetPasswordRequest {
+    ResetPassword passwordMetadata = 1;
+}
+
+message LinkUserProfileRequest {
+    string current_username = 1;
+    string previous_username = 2;
+    repeated string linking_attributes = 3;
+    int64 tenantId = 4;
+    string iamClientId = 5;
+    string iamClientSecret = 6;
+    string accessToken = 7;
+    string performedBy = 8;
+}
+
+message SynchronizeUserDBRequest {
+    int64 tenantId = 2;
+    string clientId = 4;
+}
+
+service UserManagementService {
+
+    rpc registerUser (org.apache.custos.iam.service.RegisterUserRequest) returns (org.apache.custos.iam.service.RegisterUserResponse) {
+        option (google.api.http) = {
+           post: "/user-management/v1.0.0/user"
+           body: "user"
+         };
+    }
+
+    rpc registerAndEnableUsers (org.apache.custos.iam.service.RegisterUsersRequest) returns (org.apache.custos.iam.service.RegisterUsersResponse) {
+        option (google.api.http) = {
+           post: "/user-management/v1.0.0/users"
+           body: "users"
+         };
+    }
+
+    rpc addUserAttributes (org.apache.custos.iam.service.AddUserAttributesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/user-management/v1.0.0/attributes"
+         };
+    }
+
+    rpc deleteUserAttributes (org.apache.custos.iam.service.DeleteUserAttributeRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           delete: "/user-management/v1.0.0/attributes"
+         };
+    }
+
+    rpc enableUser (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.UserRepresentation) {
+        option (google.api.http) = {
+           post: "/user-management/v1.0.0/user/activation"
+           body: "user"
+         };
+    }
+
+    rpc disableUser (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.UserRepresentation) {
+        option (google.api.http) = {
+           post: "/user-management/v1.0.0/user/deactivation"
+           body: "user"
+         };
+    }
+
+    rpc grantAdminPrivileges (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/user-management/v1.0.0/user/admin"
+           body: "user"
+         };
+    }
+
+    rpc removeAdminPrivileges (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           delete: "/user-management/v1.0.0/user/admin"
+           body: "user"
+         };
+    }
+
+    rpc addRolesToUsers (org.apache.custos.iam.service.AddUserRolesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/user-management/v1.0.0/users/roles"
+         };
+    }
+
+    rpc isUserEnabled (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           get: "/user-management/v1.0.0/user/activation/status"
+         };
+
+    }
+
+    rpc isUsernameAvailable (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           get: "/user-management/v1.0.0/user/availability"
+         };
+    }
+
+
+    rpc getUser (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.UserRepresentation) {
+        option (google.api.http) = {
+           get: "/user-management/v1.0.0/user"
+         };
+
+    }
+
+    rpc findUsers (org.apache.custos.iam.service.FindUsersRequest) returns (org.apache.custos.iam.service.FindUsersResponse) {
+        option (google.api.http) = {
+           get: "/user-management/v1.0.0/users"
+         };
+
+    }
+
+    rpc resetPassword (org.apache.custos.iam.service.ResetUserPassword) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           put: "/user-management/v1.0.0/user/password"
+         };
+
+    }
+
+
+    rpc deleteUser (org.apache.custos.iam.service.UserSearchRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           delete: "/user-management/v1.0.0/user"
+           body: "user"
+         };
+
+    }
+
+
+    rpc deleteUserRoles (org.apache.custos.iam.service.DeleteUserRolesRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           delete: "/user-management/v1.0.0/user/roles"
+         };
+    }
+
+
+    rpc updateUserProfile (UserProfileRequest) returns (org.apache.custos.user.profile.service.UserProfile) {
+
+        option (google.api.http) = {
+           put: "/user-management/v1.0.0/user/profile"
+           body: "user_profile"
+         };
+    }
+
+    rpc getUserProfile (UserProfileRequest) returns (org.apache.custos.user.profile.service.UserProfile) {
+
+        option (google.api.http) = {
+           get: "/user-management/v1.0.0/user/profile"
+         };
+    }
+    rpc deleteUserProfile (UserProfileRequest) returns (org.apache.custos.user.profile.service.UserProfile) {
+
+        option (google.api.http) = {
+           delete: "/user-management/v1.0.0/user/profile"
+         };
+
+    }
+    rpc getAllUserProfilesInTenant (UserProfileRequest) returns (org.apache.custos.user.profile.service.GetAllUserProfilesResponse) {
+
+        option (google.api.http) = {
+           get: "/user-management/v1.0.0/users/profile"
+         };
+
+
+    }
+
+    rpc linkUserProfile (LinkUserProfileRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+
+        option (google.api.http) = {
+           post: "/user-management/v1.0.0/user/profile/mapper"
+         };
+
+
+    }
+
+
+    rpc getUserProfileAuditTrails (org.apache.custos.user.profile.service.GetUpdateAuditTrailRequest) returns (org.apache.custos.user.profile.service.GetUpdateAuditTrailResponse) {
+
+        option (google.api.http) = {
+           get: "/user-management/v1.0.0/user/profile/audit"
+         };
+
+    }
+
+    rpc synchronizeUserDBs (SynchronizeUserDBRequest) returns (org.apache.custos.iam.service.OperationStatus) {
+        option (google.api.http) = {
+           post: "/user-management/v1.0.0/db/synchronize"
+        };
+    }
+
+}
+
+
+
+
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService_pb.js b/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService_pb.js
new file mode 100644
index 0000000..ef705ab
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/proto/UserManagementService_pb.js
@@ -0,0 +1,1954 @@
+// source: src/main/proto/UserManagementService.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+var google_api_annotations_pb = require('../../../google/api/annotations_pb.js');
+goog.object.extend(proto, google_api_annotations_pb);
+var UserProfileService_pb = require('../../../UserProfileService_pb.js');
+goog.object.extend(proto, UserProfileService_pb);
+var IamAdminService_pb = require('../../../IamAdminService_pb.js');
+goog.object.extend(proto, IamAdminService_pb);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.GetUserRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.GetUsersRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.LinkUserProfileRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.ResetPassword', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.ResetPasswordRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest', null, global);
+goog.exportSymbol('proto.org.apache.custos.user.management.service.UserProfileRequest', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.UserProfileRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.UserProfileRequest.displayName = 'proto.org.apache.custos.user.management.service.UserProfileRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.GetUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.GetUserRequest.displayName = 'proto.org.apache.custos.user.management.service.GetUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.GetUsersRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.GetUsersRequest.displayName = 'proto.org.apache.custos.user.management.service.GetUsersRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.ResetPassword = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.ResetPassword, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.ResetPassword.displayName = 'proto.org.apache.custos.user.management.service.ResetPassword';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.ResetPasswordRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.ResetPasswordRequest.displayName = 'proto.org.apache.custos.user.management.service.ResetPasswordRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.org.apache.custos.user.management.service.LinkUserProfileRequest.repeatedFields_, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.LinkUserProfileRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.LinkUserProfileRequest.displayName = 'proto.org.apache.custos.user.management.service.LinkUserProfileRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.displayName = 'proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.UserProfileRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    userProfile: (f = msg.getUserProfile()) && UserProfileService_pb.UserProfile.toObject(includeInstance, f),
+    clientid: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    tenantid: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    clientsecret: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.UserProfileRequest;
+  return proto.org.apache.custos.user.management.service.UserProfileRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new UserProfileService_pb.UserProfile;
+      reader.readMessage(value,UserProfileService_pb.UserProfile.deserializeBinaryFromReader);
+      msg.setUserProfile(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientsecret(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.UserProfileRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.UserProfileRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUserProfile();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      UserProfileService_pb.UserProfile.serializeBinaryToWriter
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getClientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional org.apache.custos.user.profile.service.UserProfile user_profile = 1;
+ * @return {?proto.org.apache.custos.user.profile.service.UserProfile}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getUserProfile = function() {
+  return /** @type{?proto.org.apache.custos.user.profile.service.UserProfile} */ (
+    jspb.Message.getWrapperField(this, UserProfileService_pb.UserProfile, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.user.profile.service.UserProfile|undefined} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+*/
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setUserProfile = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.clearUserProfile = function() {
+  return this.setUserProfile(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.hasUserProfile = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string clientId = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 tenantId = 3;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string accessToken = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string clientSecret = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getClientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setClientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string performedBy = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.UserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.UserProfileRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.GetUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.GetUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    username: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    usersearchrequest: (f = msg.getUsersearchrequest()) && IamAdminService_pb.UserSearchRequest.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.GetUserRequest;
+  return proto.org.apache.custos.user.management.service.GetUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.GetUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 2:
+      var value = new IamAdminService_pb.UserSearchRequest;
+      reader.readMessage(value,IamAdminService_pb.UserSearchRequest.deserializeBinaryFromReader);
+      msg.setUsersearchrequest(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.GetUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.GetUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getUsersearchrequest();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      IamAdminService_pb.UserSearchRequest.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string username = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional org.apache.custos.iam.service.UserSearchRequest userSearchRequest = 2;
+ * @return {?proto.org.apache.custos.iam.service.UserSearchRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.getUsersearchrequest = function() {
+  return /** @type{?proto.org.apache.custos.iam.service.UserSearchRequest} */ (
+    jspb.Message.getWrapperField(this, IamAdminService_pb.UserSearchRequest, 2));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.iam.service.UserSearchRequest|undefined} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest} returns this
+*/
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.setUsersearchrequest = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.user.management.service.GetUserRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.clearUsersearchrequest = function() {
+  return this.setUsersearchrequest(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.user.management.service.GetUserRequest.prototype.hasUsersearchrequest = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.GetUsersRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.GetUsersRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    email: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    offset: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    limit: jspb.Message.getFieldWithDefault(msg, 5, 0),
+    search: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    iamclientid: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    iamclientsecret: jspb.Message.getFieldWithDefault(msg, 8, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.GetUsersRequest;
+  return proto.org.apache.custos.user.management.service.GetUsersRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.GetUsersRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEmail(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setOffset(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setLimit(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSearch(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientid(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientsecret(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.GetUsersRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.GetUsersRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getOffset();
+  if (f !== 0) {
+    writer.writeInt32(
+      4,
+      f
+    );
+  }
+  f = message.getLimit();
+  if (f !== 0) {
+    writer.writeInt32(
+      5,
+      f
+    );
+  }
+  f = message.getSearch();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getIamclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getIamclientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string email = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string username = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional int32 offset = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getOffset = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setOffset = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional int32 limit = 5;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getLimit = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setLimit = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+/**
+ * optional string search = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getSearch = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setSearch = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string iamClientId = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getIamclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setIamclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string iamClientSecret = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.getIamclientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.GetUsersRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.GetUsersRequest.prototype.setIamclientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.ResetPassword.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.ResetPassword} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    password: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    iamclientid: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    iamclientsecret: jspb.Message.getFieldWithDefault(msg, 6, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.ResetPassword;
+  return proto.org.apache.custos.user.management.service.ResetPassword.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.ResetPassword} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientid(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientsecret(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.ResetPassword.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.ResetPassword} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getIamclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getIamclientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 1;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string accessToken = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string username = 3;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string password = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string iamClientId = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getIamclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setIamclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string iamClientSecret = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.getIamclientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPassword} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPassword.prototype.setIamclientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.ResetPasswordRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    passwordmetadata: (f = msg.getPasswordmetadata()) && proto.org.apache.custos.user.management.service.ResetPassword.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPasswordRequest}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.ResetPasswordRequest;
+  return proto.org.apache.custos.user.management.service.ResetPasswordRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPasswordRequest}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.org.apache.custos.user.management.service.ResetPassword;
+      reader.readMessage(value,proto.org.apache.custos.user.management.service.ResetPassword.deserializeBinaryFromReader);
+      msg.setPasswordmetadata(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.ResetPasswordRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getPasswordmetadata();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.org.apache.custos.user.management.service.ResetPassword.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional ResetPassword passwordMetadata = 1;
+ * @return {?proto.org.apache.custos.user.management.service.ResetPassword}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.getPasswordmetadata = function() {
+  return /** @type{?proto.org.apache.custos.user.management.service.ResetPassword} */ (
+    jspb.Message.getWrapperField(this, proto.org.apache.custos.user.management.service.ResetPassword, 1));
+};
+
+
+/**
+ * @param {?proto.org.apache.custos.user.management.service.ResetPassword|undefined} value
+ * @return {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} returns this
+*/
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.setPasswordmetadata = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.org.apache.custos.user.management.service.ResetPasswordRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.clearPasswordmetadata = function() {
+  return this.setPasswordmetadata(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.org.apache.custos.user.management.service.ResetPasswordRequest.prototype.hasPasswordmetadata = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.repeatedFields_ = [3];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.LinkUserProfileRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    currentUsername: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    previousUsername: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    linkingAttributesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    tenantid: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    iamclientid: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    iamclientsecret: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    accesstoken: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    performedby: jspb.Message.getFieldWithDefault(msg, 8, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.LinkUserProfileRequest;
+  return proto.org.apache.custos.user.management.service.LinkUserProfileRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCurrentUsername(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPreviousUsername(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addLinkingAttributes(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientid(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIamclientsecret(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAccesstoken(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPerformedby(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.LinkUserProfileRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getCurrentUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getPreviousUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getLinkingAttributesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+  f = message.getIamclientid();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+  f = message.getIamclientsecret();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getAccesstoken();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = message.getPerformedby();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string current_username = 1;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getCurrentUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setCurrentUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string previous_username = 2;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getPreviousUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setPreviousUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * repeated string linking_attributes = 3;
+ * @return {!Array<string>}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getLinkingAttributesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setLinkingAttributesList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.addLinkingAttributes = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.clearLinkingAttributesList = function() {
+  return this.setLinkingAttributesList([]);
+};
+
+
+/**
+ * optional int64 tenantId = 4;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional string iamClientId = 5;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getIamclientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setIamclientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
+/**
+ * optional string iamClientSecret = 6;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getIamclientsecret = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setIamclientsecret = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string accessToken = 7;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getAccesstoken = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setAccesstoken = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string performedBy = 8;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.getPerformedby = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.LinkUserProfileRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.LinkUserProfileRequest.prototype.setPerformedby = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    tenantid: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    clientid: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest;
+  return proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setTenantid(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setClientid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTenantid();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getClientid();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 tenantId = 2;
+ * @return {number}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.getTenantid = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.setTenantid = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional string clientId = 4;
+ * @return {string}
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.getClientid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest} returns this
+ */
+proto.org.apache.custos.user.management.service.SynchronizeUserDBRequest.prototype.setClientid = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+goog.object.extend(exports, proto.org.apache.custos.user.management.service);
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/resources/application.properties b/custos-integration-services/user-management-service-parent/user-management-service/src/main/resources/application.properties
new file mode 100644
index 0000000..5798f47
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/resources/application.properties
@@ -0,0 +1,28 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+server.port=8080
+grpc.port=7000
+spring.application.name=userManagementService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
diff --git a/custos-integration-services/user-management-service-parent/user-management-service/src/main/resources/bootstrap.properties b/custos-integration-services/user-management-service-parent/user-management-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++ b/custos-integration-services/user-management-service-parent/user-management-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default
diff --git a/custos-samples/configs/settings.ini b/custos-samples/configs/settings.ini
deleted file mode 100644
index f6289bf..0000000
--- a/custos-samples/configs/settings.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[CustosServer]
-SERVER_HOST = custos.scigap.org
-SERVER_SSL_PORT = 31499
-;CLIENT_ID = 
-;CLIENT_SEC = 
-
-CLIENT_ID = 
-CLIENT_SEC = 
diff --git a/custos-samples/samples/group_management_samples.py b/custos-samples/samples/group_management_samples.py
deleted file mode 100644
index a0082ee..0000000
--- a/custos-samples/samples/group_management_samples.py
+++ /dev/null
@@ -1,58 +0,0 @@
-import os
-
-from custos.clients.group_management_client import GroupManagementClient
-
-from custos.transport.settings import CustosServerClientSettings
-import custos.clients.utils.utilities as utl
-
-# load root directoty
-BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-# get settings file path (settings file path reside in configs folder under home directory)
-settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
-
-# read settings
-custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
-
-# create custos user management client
-group_management_client = GroupManagementClient(custos_settings)
-
-# obtain base 64 encoded token for tenant
-b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
-
-
-def create_group(name, description, owner_id):
-    response = group_management_client.create_groups(token=b64_encoded_custos_token, name=name,
-                                                     description=description,
-                                                     owner_id=owner_id)
-    print(response)
-    return response
-
-
-def add_user_to_group(username, group_id, membership_type):
-    response = group_management_client.add_user_to_group(token=b64_encoded_custos_token,
-                                                         username=username,
-                                                         group_id=group_id,
-                                                         membership_type=membership_type)
-    print(response)
-
-
-def add_child_group_to_parent_group(parent_group_id, child_group_id):
-    response = group_management_client.add_child_group(token=b64_encoded_custos_token, parent_group_id=parent_group_id,
-                                                       child_group_id=child_group_id)
-    print(response)
-
-
-def remove_child_group(parent_group_id, child_group_id):
-    response = group_management_client.add_child_group(token=b64_encoded_custos_token, parent_group_id=parent_group_id,
-                                                       child_group_id=child_group_id)
-    print(response)
-
-
-create_group("Group A", "Paren group", "TestUser4")
-create_group("Group B", "Child group", "TestUser4")
-
-add_user_to_group("Testuser5", "602336d5-e193-41ac-bde6-eb36a73f687e", "Member")
-
-add_child_group_to_parent_group("8b0f8241-e995-496e-a4f5-bdbde4235215", "602336d5-e193-41ac-bde6-eb36a73f687e")
-remove_child_group("8b0f8241-e995-496e-a4f5-bdbde4235215", "602336d5-e193-41ac-bde6-eb36a73f687e")
diff --git a/custos-samples/samples/identity_management_samples.py b/custos-samples/samples/identity_management_samples.py
deleted file mode 100644
index d135f57..0000000
--- a/custos-samples/samples/identity_management_samples.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import os
-
-from custos.clients.identity_management_client import IdentityManagementClient
-
-from custos.transport.settings import CustosServerClientSettings
-import custos.clients.utils.utilities as utl
-
-# load APIServerClient with default configuration
-BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
-
-# logger.info(settings_path)
-custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
-
-id_client = IdentityManagementClient(custos_settings)
-
-b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
-
-
-def login(username, password):
-    resp = id_client.authenticate(token=b64_encoded_custos_token, username=username, password=password)
-    print(resp)
-
-
-def obtain_access_token_from_code(redirect_uri, code):
-    resp = id_client.token(token=b64_encoded_custos_token, redirect_uri=redirect_uri, code=code,
-                           grant_type="authorization_code")
-    print(resp)
-
-
-def get_oidc_configuration(client_id):
-    response = id_client.get_oidc_configuration(token=b64_encoded_custos_token, client_id=client_id)
-    print(response)
-
-
-def logout(refresh_token):
-    response = id_client.end_user_session(token=b64_encoded_custos_token, refresh_token=refresh_token)
-    print(response)
-
diff --git a/custos-samples/samples/secret_management_samples.py b/custos-samples/samples/secret_management_samples.py
deleted file mode 100644
index 229a6a4..0000000
--- a/custos-samples/samples/secret_management_samples.py
+++ /dev/null
@@ -1,62 +0,0 @@
-import os
-
-from custos.clients.resource_secret_management_client import ResourceSecretManagementClient
-
-from custos.transport.settings import CustosServerClientSettings
-import custos.clients.utils.utilities as utl
-
-# load root directoty
-BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-# get settings file path (settings file path reside in configs folder under home directory)
-settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
-
-# read settings
-custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
-
-# create custos user management client
-resource_management_client = ResourceSecretManagementClient(custos_settings)
-
-# obtain base 64 encoded token for tenant
-b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
-
-
-def generateSSH_key(owner_id, description):
-    response = resource_management_client.add_ssh_credential(token=b64_encoded_custos_token,
-                                                             client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                             owner_id=owner_id,
-                                                             description=description)
-    print(response)
-    return response
-
-
-def getSSHKey(ssh_credential_token):
-    response = resource_management_client.get_ssh_credential(token=b64_encoded_custos_token,
-                                                             client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                             ssh_credential_token=ssh_credential_token)
-    print(response)
-    return response
-
-
-def addPasswordCredential(owner_id, description, password):
-    response = resource_management_client.add_password_credential(token=b64_encoded_custos_token,
-                                                                  client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                                  owner_id=owner_id,
-                                                                  description=description,
-                                                                  password=password)
-    print(response)
-    return response
-
-
-def getPasswordCredential(password_credential_token):
-    response = resource_management_client.get_password_credential(token=b64_encoded_custos_token,
-                                                                  client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                                  password_credential_token=password_credential_token)
-    print(response)
-    return response
-
-
-generateSSH_key("TestUser5", "My Gateway SSH Key")
-addPasswordCredential("TestUser5", "My admin password", "asaxsxasxasx")
-getSSHKey("655e8845-9afa-4251-bb0e-c1eb42bec2fc")
-getPasswordCredential("a575726a-3e2a-41d1-ad08-06a97dbae903")
diff --git a/custos-samples/samples/secure_resources_with_custos_simulation.py b/custos-samples/samples/secure_resources_with_custos_simulation.py
deleted file mode 100644
index 7877a43..0000000
--- a/custos-samples/samples/secure_resources_with_custos_simulation.py
+++ /dev/null
@@ -1,361 +0,0 @@
-import os
-import json
-
-from custos.clients.user_management_client import UserManagementClient
-from custos.clients.group_management_client import GroupManagementClient
-from custos.clients.resource_secret_management_client import ResourceSecretManagementClient
-from custos.clients.sharing_management_client import SharingManagementClient
-
-from custos.transport.settings import CustosServerClientSettings
-import custos.clients.utils.utilities as utl
-
-from google.protobuf.json_format import MessageToJson
-
-# load root directoty
-BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-# get settings file path (settings file path reside in configs folder under home directory)
-settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
-
-# read settings
-custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
-
-# create custos user management client
-user_management_client = UserManagementClient(custos_settings)
-
-# create custos group management client
-group_management_client = GroupManagementClient(custos_settings)
-
-# create custos resource secret client
-resource_secret_client = ResourceSecretManagementClient(custos_settings)
-
-# create sharing management client
-sharing_management_client = SharingManagementClient(custos_settings)
-
-# obtain base 64 encoded token for tenant
-b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
-
-owner_id = "admin"
-
-created_groups = {}
-
-resource_ids = []
-
-
-def verifiy_admin_user():
-    response = user_management_client.get_user(token=b64_encoded_custos_token, username=owner_id)
-    user_management_client.update_user_profile(
-        token=b64_encoded_custos_token,
-        username=response.username,
-        email=response.email,
-        first_name=response.first_name,
-        last_name=response.last_name)
-
-
-def register_users(users):
-    for user in users:
-        print("Registering user: " + user['username'])
-        user_management_client.register_user(token=b64_encoded_custos_token,
-                                             username=user['username'],
-                                             first_name=user['first_name'],
-                                             last_name=user['last_name'],
-                                             password=user['password'],
-                                             email=user['email'],
-                                             is_temp_password=False)
-
-        user_management_client.enable_user(token=b64_encoded_custos_token, username=user['username'])
-
-
-def create_groups(groups):
-    for group in groups:
-        print("Creating group: " + group['name'])
-        grResponse = group_management_client.create_groups(token=b64_encoded_custos_token,
-                                                           name=group['name'],
-                                                           description=group['description'],
-                                                           owner_id=group['owner_id'])
-        resp = MessageToJson(grResponse)
-        respData = json.loads(resp)
-        created_groups[respData['groups'][0]['name']] = respData['groups'][0]['id']
-
-
-def allocate_users_to_groups(user_group_mapping):
-    for usr_map in user_group_mapping:
-        group_id = created_groups[usr_map['group_name']]
-        print("Assigning user " + usr_map['username'] + " to group " + usr_map['group_name'])
-        group_management_client.add_user_to_group(token=b64_encoded_custos_token,
-                                                  username=usr_map['username'],
-                                                  group_id=group_id,
-                                                  membership_type='Member'
-                                                  )
-
-
-def allocate_child_group_to_parent_group(gr_gr_mapping):
-    for gr_map in gr_gr_mapping:
-        child_id = created_groups[gr_map['child_name']]
-        parent_id = created_groups[gr_map['parent_name']]
-        print("Assigning child group " + gr_map['child_name'] + " to parent group " + gr_map['parent_name'])
-        group_management_client.add_child_group(token=b64_encoded_custos_token,
-                                                parent_group_id=parent_id,
-                                                child_group_id=child_id)
-
-
-def create_resource():
-    response = resource_secret_client.add_ssh_credential(
-        token=b64_encoded_custos_token,
-        client_id=custos_settings.CUSTOS_CLIENT_ID,
-        owner_id='admin',
-        description='Testing SSH Key')
-    resource_ids.append(response.token)
-
-
-def create_permissions(permissions):
-    for perm in permissions:
-        print("Creating permission " + perm['id'])
-        sharing_management_client.create_permission_type(token=b64_encoded_custos_token,
-                                                         client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                         id=perm['id'],
-                                                         name=perm['name'],
-                                                         description=perm['description'])
-
-
-def create_entity_types(entity_types):
-    for type in entity_types:
-        print("Creating entity types " + type['id'])
-        sharing_management_client.create_entity_type(token=b64_encoded_custos_token,
-                                                     client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                     id=type['id'],
-                                                     name=type['name'],
-                                                     description=type['description'])
-
-
-def register_resources(resources):
-    for resource in resources:
-        print("Register resources " + resource['id'])
-        sharing_management_client.create_entity(token=b64_encoded_custos_token,
-                                                client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                id=resource['id'],
-                                                name=resource['name'],
-                                                description=resource['description'],
-                                                owner_id=resource['user_id'],
-                                                type=resource['type'],
-                                                parent_id='')
-
-
-def share_resource_with_user(sharings):
-    for shr in sharings:
-        print("Sharing entity " + shr['entity_id'] + " with user " + shr['user_id'] + " with permission " + shr[
-            'permission_type'])
-        sharing_management_client.share_entity_with_users(token=b64_encoded_custos_token,
-                                                          client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                          entity_id=shr['entity_id'],
-                                                          permission_type=shr['permission_type'],
-                                                          user_id=shr['user_id']
-                                                          )
-
-
-def share_resource_with_group(gr_sharings):
-    for shr in gr_sharings:
-        group_id = created_groups[shr['group_name']]
-        print("Sharing entity " + shr['entity_id'] + " with group " + shr['group_name'] + " with permission " + shr[
-            'permission_type'])
-        sharing_management_client.share_entity_with_groups(token=b64_encoded_custos_token,
-                                                           client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                           entity_id=shr['entity_id'],
-                                                           permission_type=shr['permission_type'],
-                                                           group_id=group_id)
-
-
-def check_user_permissions(users):
-    for user in users:
-        access = sharing_management_client.user_has_access(token=b64_encoded_custos_token,
-                                                           client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                           entity_id=resource_ids[0],
-                                                           permission_type="READ",
-                                                           user_id=user['username'])
-        usr = user['username']
-        print("Access for user " + usr + " : " + str(access))
-
-
-users = [
-    {
-        'username': 'UserA',
-        'first_name': 'Aaron',
-        'last_name': 'Bob',
-        'password': '1234',
-        'email': 'a@gmail.com'
-    },
-    {
-        'username': 'UserB',
-        'first_name': 'Baron',
-        'last_name': 'Bob',
-        'password': '1234',
-        'email': 'b@gmail.com'
-    },
-    {
-        'username': 'UserC',
-        'first_name': 'Caron',
-        'last_name': 'Bob',
-        'password': '1234',
-        'email': 'c@gmail.com'
-    },
-    {
-        'username': 'UserD',
-        'first_name': 'Daron',
-        'last_name': 'Bob',
-        'password': '1234',
-        'email': 'd@gmail.com'
-    },
-    {
-        'username': 'UserE',
-        'first_name': 'Earon',
-        'last_name': 'Bob',
-        'password': '1234',
-        'email': 'e@gmail.com'
-    },
-    {
-        'username': 'UserF',
-        'first_name': 'Faron',
-        'last_name': 'Bob',
-        'password': '1234',
-        'email': 'f@gmail.com'
-    }
-]
-
-groups = [
-    {
-        'name': 'groupA',
-        'description': 'Group L',
-        'owner_id': 'admin'
-    },
-    {
-        'name': 'groupB',
-        'description': 'Group B',
-        'owner_id': 'admin'
-    },
-    {
-        'name': 'groupC',
-        'description': 'Group C',
-        'owner_id': 'admin'
-    }
-]
-
-user_group_mapping = [
-    {
-        'group_name': 'groupA',
-        'username': 'UserA'
-    },
-    {
-        'group_name': 'groupA',
-        'username': 'UserB'
-    },
-    {
-        'group_name': 'groupB',
-        'username': 'UserC'
-    },
-    {
-        'group_name': 'groupB',
-        'username': 'UserD'
-    },
-    {
-        'group_name': 'groupC',
-        'username': 'UserE'
-    },
-    {
-        'group_name': 'groupC',
-        'username': 'UserF'
-    }
-]
-
-child_gr_parent_gr_mapping = [
-    {
-        "child_name": "groupB",
-        "parent_name": "groupA"
-    }
-]
-
-permissions = [
-    {
-        'id': 'OWNER',
-        'name': 'OWNER',
-        'description': 'Owner permission'
-    },
-    {
-        'id': 'READ',
-        'name': 'READ',
-        'description': 'Read permission'
-    },
-    {
-        'id': 'WRITE',
-        'name': 'WRITE',
-        'description': 'WRITE permission'
-    }
-]
-entity_types = [
-    {
-        'id': 'SECRET',
-        'name': 'SECRET',
-        'description': 'SECRET Keys'
-    }
-]
-
-verifiy_admin_user()
-
-# Register users
-register_users(users)
-
-# Create groups
-create_groups(groups)
-
-# Allocate users to groups
-allocate_users_to_groups(user_group_mapping)
-
-# Allocate child groups to parent group
-allocate_child_group_to_parent_group(child_gr_parent_gr_mapping)
-
-# Creare resource
-create_resource()
-
-# Create permissions
-create_permissions(permissions)
-
-# Create entity types
-create_entity_types(entity_types)
-
-resources = [
-    {
-        'id': resource_ids[0],
-        'name': 'SECRET',
-        'description': 'Register SSH Key Id',
-        'user_id': 'admin',
-        'type': 'SECRET'
-    }
-]
-
-sharings = [
-    {
-        "entity_id": resource_ids[0],
-        "permission_type": "READ",
-        "type": "SECRET",
-        "user_id": "UserF"
-    }
-]
-
-gr_sharings = [{
-
-    "entity_id": resource_ids[0],
-    "permission_type": "READ",
-    "type": "SSH_KEY",
-    "group_name": 'groupA'
-}]
-
-# Register resources
-register_resources(resources)
-
-# Share resource with users
-share_resource_with_user(sharings)
-
-# Share resource with group
-share_resource_with_group(gr_sharings)
-
-# Check user permissions
-check_user_permissions(users)
diff --git a/custos-samples/samples/sharing_management_samples.py b/custos-samples/samples/sharing_management_samples.py
deleted file mode 100644
index d94eeae..0000000
--- a/custos-samples/samples/sharing_management_samples.py
+++ /dev/null
@@ -1,89 +0,0 @@
-import os
-
-from custos.clients.sharing_management_client import SharingManagementClient
-
-from custos.transport.settings import CustosServerClientSettings
-import custos.clients.utils.utilities as utl
-
-# load root directoty
-BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-# get settings file path (settings file path reside in configs folder under home directory)
-settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
-
-# read settings
-custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
-
-# create custos user management client
-sharing_management_client = SharingManagementClient(custos_settings)
-
-# obtain base 64 encoded token for tenant
-b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
-
-
-def create_permission_type(id, name, description):
-    response = sharing_management_client.create_permission_type(token=b64_encoded_custos_token,
-                                                                client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                                id=id,
-                                                                name=name,
-                                                                description=description)
-    print(response)
-
-
-def create_entity_type(id, name, description):
-    response = sharing_management_client.create_entity_type(token=b64_encoded_custos_token,
-                                                            client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                            id=id,
-                                                            name=name,
-                                                            description=description)
-    print(response)
-
-
-def create_entity(id, name, description, owner_id, type):
-    response = sharing_management_client.create_entity(token=b64_encoded_custos_token,
-                                                       client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                       id=id,
-                                                       name=name,
-                                                       description=description,
-                                                       owner_id=owner_id,
-                                                       type=type,
-                                                       parent_id='')
-    print(response)
-
-
-def share_entity_with_user(entity_id, permission_type, user_id):
-    response = sharing_management_client.share_entity_with_users(token=b64_encoded_custos_token,
-                                                                 client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                                 entity_id=entity_id,
-                                                                 permission_type=permission_type,
-                                                                 user_id=user_id)
-    print(response)
-
-
-def share_entity_with_group(entity_id, permission_type, group_id):
-    response = sharing_management_client.share_entity_with_groups(token=b64_encoded_custos_token,
-                                                                  client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                                  entity_id=entity_id,
-                                                                  permission_type=permission_type,
-                                                                  group_id=group_id)
-    print(response)
-
-
-def check_user_has_access(entity_id, permission_type, user_id):
-    response = sharing_management_client.user_has_access(token=b64_encoded_custos_token,
-                                                         client_id=custos_settings.CUSTOS_CLIENT_ID,
-                                                         entity_id=entity_id,
-                                                         permission_type=permission_type,
-                                                         user_id=user_id)
-    print(response)
-
-
-# create_permission_type('RW', 'Read and Write', 'Read write permissions')
-# create_entity_type("CRED_TOKEN", "Credential Token", "This is credential token")
-
-create_entity('655e8845-9afa-4251-bb0e-c1ebasasx42bec2fcASD', 'Password Token', 'This is password token', 'TestUser5',
-              'CRED_TOKEN')
-# share_entity_with_user('655e8845-9afa-4251-bb0e-c1eb42bec2fc', 'RW', 'TestUser4')
-# share_entity_with_group('655e8845-9afa-4251-bb0e-c1eb42bec2fc', 'RW', '602336d5-e193-41ac-bde6-eb36a73f687e')
-#
-# check_user_has_access('655e8845-9afa-4251-bb0e-c1eb42bec2fc', 'RW', 'TestUser4')
diff --git a/custos-samples/samples/user_management_samples.py b/custos-samples/samples/user_management_samples.py
deleted file mode 100644
index 6b0b489..0000000
--- a/custos-samples/samples/user_management_samples.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import os
-
-from custos.clients.user_management_client import UserManagementClient
-
-from custos.transport.settings import CustosServerClientSettings
-import custos.clients.utils.utilities as utl
-
-# load root directoty
-BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-#get settings file path (settings file path reside in configs folder under home directory)
-settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
-
-# read settings
-custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
-
-# create custos user management client
-user_management_client = UserManagementClient(custos_settings)
-
-# obtain base 64 encoded token for tenant
-b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
-
-
-def register_user():
-    response = user_management_client.register_user(token=b64_encoded_custos_token,
-                                                    username="TestUser5",
-                                                    first_name="Watson",
-                                                    last_name="Christe",
-                                                    password="1234",
-                                                    email="wat@gmail.com",
-                                                    is_temp_password=False)
-    print(response)
-
-
-def enable_user():
-    response = user_management_client.enable_user(token=b64_encoded_custos_token,
-                                                  username="TestUser5")
-    print(response)
-
-
-def get_user():
-    response = user_management_client.get_user(token=b64_encoded_custos_token,
-                                               username="TestUser5")
-    print(response)
-
-
-def update_user():
-    response = user_management_client.update_user_profile(token=b64_encoded_custos_token,
-                                                          username="TestUser5",
-                                                          first_name="Jimmy",
-                                                          last_name="Jhon",
-                                                          email="wat@gmail.com")
-    print(response)
-
-
-def find_users():
-    response = user_management_client.find_users(token=b64_encoded_custos_token, offset=0, limit=1,
-                                                 username="TestUser5")
-    print(response)
-
-
-register_user()
-enable_user()
-get_user()
-update_user()
-find_users()
diff --git a/custos-tests/pom.xml b/custos-tests/pom.xml
new file mode 100644
index 0000000..df88351
--- /dev/null
+++ b/custos-tests/pom.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-tests</artifactId>
+
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>identity-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>group-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>agent-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>user-management-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <suiteXmlFiles>
+                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
+                    </suiteXmlFiles>
+                    <skipTests>true</skipTests>
+                </configuration>
+            </plugin>
+        </plugins>
+
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/custos-tests/src/test/java/org/apache/custos/integration/tests/AgentManagementTests.java b/custos-tests/src/test/java/org/apache/custos/integration/tests/AgentManagementTests.java
new file mode 100644
index 0000000..45f663d
--- /dev/null
+++ b/custos-tests/src/test/java/org/apache/custos/integration/tests/AgentManagementTests.java
@@ -0,0 +1,241 @@
+package org.apache.custos.integration.tests;
+
+import com.google.protobuf.Struct;
+import com.google.protobuf.Value;
+import org.apache.custos.agent.management.client.AgentManagementClient;
+import org.apache.custos.agent.management.service.AgentRegistrationResponse;
+import org.apache.custos.iam.service.Agent;
+import org.apache.custos.iam.service.OperationStatus;
+import org.apache.custos.iam.service.UserAttribute;
+import org.apache.custos.identity.management.client.IdentityManagementClient;
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Parameters;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class contains AgentManagement tests
+ */
+public class AgentManagementTests {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AgentManagementTests.class);
+
+    private String LOG_SUFFIX = "...........................";
+
+    private AgentManagementClient agentManagementClient;
+    private IdentityManagementClient identityManagementClient;
+
+
+    private String clientId;
+
+    private String adminToken;
+
+    private String registeredAgentId;
+
+    private String agentId;
+
+    private String agentSec;
+
+    @Parameters({"server-host", "server-port", "client-id", "client-sec", "admin-username", "admin-password"})
+    @BeforeClass(groups = {"agent-management"})
+    public void setup(String serverHost, String serverPort, String clientId, String clientSec,
+                      String adminUsername, String adminPassword) throws IOException {
+        LOGGER.info("Initiating agent management test cases  " + LOG_SUFFIX);
+        agentManagementClient = new AgentManagementClient(serverHost, Integer.valueOf(serverPort), clientId, clientSec);
+        identityManagementClient = new IdentityManagementClient(serverHost, Integer.valueOf(serverPort), clientId, clientSec);
+        Struct struct = identityManagementClient.getToken(null,
+                null, adminUsername, adminPassword, null, "password");
+        Value value = struct.getFieldsMap().get("access_token");
+        this.adminToken = value.getStringValue();
+        this.clientId = clientId;
+    }
+
+
+    @Test(groups = {"agent-management"})
+    public void enableAgents() {
+        LOGGER.info("Executing enable agents test case ");
+        OperationStatus status = agentManagementClient.enableAgents(adminToken);
+        Assert.assertTrue(status.getStatus());
+    }
+
+
+    @Test(groups = {"agent-management"}, dependsOnMethods = {"enableAgents"})
+    public void registerAgent() {
+        LOGGER.info("Executing register agent test case ");
+        registeredAgentId = getAlphaNumericString(7);
+        List<String> arrayList = new ArrayList<>();
+        arrayList.add("true");
+        UserAttribute attribute = UserAttribute.newBuilder()
+                .setKey("server_access")
+                .addAllValues(arrayList)
+                .build();
+        UserAttribute[] attributes = {attribute};
+        String[] realmRoles = {};
+        AgentRegistrationResponse registrationResponse = agentManagementClient.
+                registerAndEnableAgent(adminToken, registeredAgentId, realmRoles, attributes);
+        agentId = registrationResponse.getId();
+        Assert.assertEquals(agentId, registeredAgentId);
+        agentSec = registrationResponse.getSecret();
+    }
+
+    @Test(groups = {"agent-management"}, dependsOnMethods = {"registerAgent"})
+    public void getAgent() {
+        LOGGER.info("Executing get agent test case ");
+        Agent agent = agentManagementClient.getAgent(adminToken, agentId);
+        Assert.assertTrue(agent.getId().equalsIgnoreCase(agentId));
+        Assert.assertTrue(!agent.getAttributesList().isEmpty());
+        List<UserAttribute> attribute = agent.getAttributesList();
+        boolean attrMatched = false;
+
+        for (UserAttribute userAttribute : attribute) {
+            if (userAttribute.getKey().equals("server_access") && userAttribute.getValuesList().contains("true")) {
+                attrMatched = true;
+            }
+        }
+        Assert.assertTrue(attrMatched);
+
+    }
+
+    @Test(groups = {"agent-management"}, dependsOnMethods = {"getAgent"})
+    public void disableAgent() {
+        LOGGER.info("Executing disable agent test case ");
+        OperationStatus status = agentManagementClient.disableAgent(adminToken, agentId);
+        Assert.assertTrue(status.getStatus());
+    }
+
+    @Test(groups = {"agent-management"}, dependsOnMethods = {"disableAgent"})
+    public void enableAgent() {
+        LOGGER.info("Executing enable agent test case ");
+        OperationStatus status = agentManagementClient.enableAgent(adminToken, agentId);
+        Assert.assertTrue(status.getStatus());
+    }
+
+
+    @Test(groups = {"agent-management"}, dependsOnMethods = {"enableAgent"})
+    public void addAgentAttribute() {
+        LOGGER.info("Executing add agent attribute test case ");
+
+
+        List<String> arrayList = new ArrayList<>();
+        arrayList.add("testing");
+        UserAttribute attribute = UserAttribute.newBuilder()
+                .setKey("test-atr")
+                .addAllValues(arrayList)
+                .build();
+        UserAttribute[] attributes = {attribute};
+
+        String[] agents = {agentId};
+
+        OperationStatus status = agentManagementClient.addAgentAttributes(adminToken, agents, attributes);
+        Assert.assertTrue(status.getStatus());
+
+        Agent agent = agentManagementClient.getAgent(adminToken, agentId);
+
+        List<UserAttribute> atrs = agent.getAttributesList();
+        boolean attrMatched = false;
+
+        for (UserAttribute userAttribute : atrs) {
+            if (userAttribute.getKey().equals("test-atr") && userAttribute.getValuesList().contains("testing")) {
+                attrMatched = true;
+            }
+        }
+
+        Assert.assertTrue(attrMatched);
+
+    }
+
+
+    @Test(groups = {"agent-management"}, dependsOnMethods = {"addAgentAttribute"})
+    public void deleteAgentAttribute() {
+        LOGGER.info("Executing delete agent attribute test case ");
+
+        List<String> arrayList = new ArrayList<>();
+        arrayList.add("testing");
+        UserAttribute attribute = UserAttribute.newBuilder()
+                .setKey("test-atr")
+                .addAllValues(arrayList)
+                .build();
+        UserAttribute[] attributes = {attribute};
+
+        String[] agents = {agentId};
+
+        OperationStatus status = agentManagementClient.deleteAgentAttributes(adminToken, agents, attributes);
+        Assert.assertTrue(status.getStatus());
+
+        Agent agent = agentManagementClient.getAgent(adminToken, agentId);
+
+        List<UserAttribute> atrs = agent.getAttributesList();
+        boolean attrMatched = true;
+
+        for (UserAttribute userAttribute : atrs) {
+            if (userAttribute.getKey().equals("test-atr") && userAttribute.getValuesList().contains("testing")) {
+                attrMatched = false;
+            }
+        }
+
+        Assert.assertTrue(attrMatched);
+
+    }
+
+    @Test(groups = {"agent-management"}, dependsOnMethods = {"deleteAgentAttribute"})
+    public void getAgentToken() {
+        LOGGER.info("Executing get  agent token test case ");
+        Struct struct = identityManagementClient.getAgentToken(clientId, agentId,
+                agentSec, "client_credentials", null);
+        Value value = struct.getFieldsMap().get("access_token");
+        Assert.assertTrue(!value.getStringValue().isEmpty());
+    }
+
+    @Test(groups = {"agent-management"}, dependsOnMethods = {"getAgentToken"})
+    public void deleteAgent() {
+        LOGGER.info("Executing delete  agent token test case ");
+        OperationStatus status = agentManagementClient.deleteAgent(adminToken, agentId);
+        Assert.assertTrue(status.getStatus());
+    }
+
+    @AfterClass(groups = {"agent-management"})
+    public void cleanup() {
+        LOGGER.info("Completing agent management tests " + LOG_SUFFIX);
+        agentManagementClient = null;
+        identityManagementClient = null;
+        clientId = null;
+        adminToken = null;
+        registeredAgentId = null;
+        agentId = null;
+        agentSec = null;
+
+    }
+
+    static String getAlphaNumericString(int n) {
+
+        // chose a Character random from this String
+        String AlphaNumericString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
+                "abcdefghijklmnopqrstuvxyz"
+                + "0123456789";
+
+        // create StringBuffer size of AlphaNumericString
+        StringBuilder sb = new StringBuilder(n);
+
+        for (int i = 0; i < n; i++) {
+
+            // generate a random number between
+            // 0 to AlphaNumericString variable length
+            int index
+                    = (int) (AlphaNumericString.length()
+                    * Math.random());
+
+            // add Character one by one in end of sb
+            sb.append(AlphaNumericString
+                    .charAt(index));
+        }
+        return sb.toString();
+    }
+
+}
diff --git a/custos-tests/src/test/java/org/apache/custos/integration/tests/TenantManagementTests.java b/custos-tests/src/test/java/org/apache/custos/integration/tests/TenantManagementTests.java
new file mode 100644
index 0000000..23a8273
--- /dev/null
+++ b/custos-tests/src/test/java/org/apache/custos/integration/tests/TenantManagementTests.java
@@ -0,0 +1,193 @@
+package org.apache.custos.integration.tests;
+
+import org.apache.custos.iam.service.AllRoles;
+import org.apache.custos.iam.service.RoleRepresentation;
+import org.apache.custos.tenant.management.service.CreateTenantResponse;
+import org.apache.custos.tenant.management.service.GetTenantResponse;
+import org.apache.custos.tenant.manamgement.client.TenantManagementClient;
+import org.apache.custos.tenant.profile.service.GetAllTenantsResponse;
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Parameters;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+
+/**
+ * This class contains integration tests for Tenant Management
+ */
+public class TenantManagementTests {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(TenantManagementTests.class);
+
+    private String LOG_SUFFIX = "...........................";
+
+
+    private TenantManagementClient tenantManagementClient;
+
+    private String serverHost;
+    private String serverPort;
+
+    private String clientId;
+    private String clientSec;
+
+
+    @Parameters({"server-host", "server-port", "client-id", "client-sec"})
+    @BeforeClass(groups = {"tenant-management"})
+    public void setup(String serverHost, String serverPort, String clientId, String clientSec) throws IOException {
+        LOGGER.info("Initiating tenant management test cases  " + LOG_SUFFIX);
+        this.serverHost = serverHost;
+        this.serverPort = serverPort;
+        tenantManagementClient = new TenantManagementClient(serverHost, Integer.valueOf(serverPort), clientId, clientSec);
+
+    }
+
+
+    @Test(groups = {"tenant-management"})
+    public void createTenant() {
+        LOGGER.info("Executing createTenant test case ");
+
+
+        String[] contants = {
+                "custos@airavata.apache.org"
+        };
+
+        String[] redirectURI = {"http://localhost:8080/callback"};
+
+        CreateTenantResponse response = tenantManagementClient.registerTenant("Testing tenant",
+                "custos@airavata.apache.org",
+                "Merry",
+                "Jhonson",
+                "custos@airavata.apache.org",
+                "testuser",
+                "12345",
+                contants,
+                redirectURI,
+                "https://test.custos.org",
+                "email openid profile org.cilogon.userinfo",
+                "test.custos.org",
+                "https://test.custos.org",
+                "Integration tenant client"
+        );
+
+        Assert.assertTrue(response.getIsActivated());
+        clientId = response.getClientId();
+        clientSec = response.getClientSecret();
+
+    }
+
+    @Test(groups = {"tenant-management"}, dependsOnMethods = {"createTenant"})
+    public void getTenant() {
+        LOGGER.info("Executing getTenant test case ");
+        GetTenantResponse response = tenantManagementClient.getTenant(clientId);
+        Assert.assertEquals(response.getClientName(), "Testing tenant");
+        Assert.assertEquals(response.getRequesterEmail(), "custos@airavata.apache.org");
+        Assert.assertEquals(response.getScope(), "email openid profile org.cilogon.userinfo");
+        Assert.assertTrue(response.getRedirectUrisList().contains("http://localhost:8080/callback"));
+
+    }
+
+
+    @Test(groups = {"tenant-management"}, dependsOnMethods = {"getTenant"})
+    public void getChildTenants() {
+        LOGGER.info("Executing getChildTenant test case ");
+        GetAllTenantsResponse response = tenantManagementClient.getChildTenants(2, 0, "ACTIVE");
+
+        Assert.assertTrue(response.getTenantCount() > 0);
+
+
+    }
+
+
+    @Test(groups = {"tenant-management"}, dependsOnMethods = {"getChildTenants"})
+    public void updateTenant() {
+        LOGGER.info("Executing updateTenant test case");
+
+        String[] contants = {
+                "custos@airavata.apache.org"
+        };
+
+        String[] redirectURI = {"http://localhost:8080/callback", "http://localhost:8080/callback/updated"};
+
+        GetTenantResponse response = tenantManagementClient.updateTenant(clientId,
+                "Testing tenant updated",
+                "custos@airavata.apache.org",
+                "Merry",
+                "Jhonson",
+                "custos@airavata.apache.org",
+                "testuser",
+                "12345",
+                contants,
+                redirectURI,
+                "https://test.custos.org",
+                "email openid profile org.cilogon.userinfo",
+                "test.custos.org",
+                "https://test.custos.org",
+                "Integration tenant client"
+        );
+
+        Assert.assertEquals(response.getClientName(), "Testing tenant updated");
+        Assert.assertTrue(response.getRedirectUrisList().contains("http://localhost:8080/callback/updated"));
+    }
+
+    @Test(groups = {"tenant-management"}, dependsOnMethods = {"updateTenant"})
+    public void addTenantRoles() throws IOException {
+        LOGGER.info("Executing addTenantRoles testcase ");
+
+        TenantManagementClient tenantManagementClient = new TenantManagementClient(this.serverHost,
+                Integer.valueOf(this.serverPort), clientId, clientSec);
+
+        RoleRepresentation roleRepresentation = RoleRepresentation.newBuilder()
+                .setName("testrole")
+                .setDescription("This is testrole").build();
+        RoleRepresentation[] roleRepresentations = {roleRepresentation};
+        AllRoles allRoles = tenantManagementClient.addTenantRoles(roleRepresentations, false);
+
+        Assert.assertTrue(allRoles.getRolesCount() > 0);
+
+        boolean isContain = false;
+
+        for (RoleRepresentation representation : allRoles.getRolesList()) {
+
+            if (representation.getName().equals("testrole")) {
+                isContain = true;
+            }
+        }
+
+        Assert.assertTrue(isContain);
+
+        AllRoles clientRoles = tenantManagementClient.addTenantRoles(roleRepresentations, true);
+        boolean isClientRoleContain = false;
+
+        for (RoleRepresentation representation : clientRoles.getRolesList()) {
+
+            if (representation.getName().equals("testrole")) {
+                isClientRoleContain = true;
+            }
+        }
+        Assert.assertTrue(isClientRoleContain);
+
+    }
+
+
+    @Test(groups = {"tenant-management"}, dependsOnMethods = {"addTenantRoles"})
+    public void deleteTenant() {
+        LOGGER.info("Executing delete tenant test");
+        tenantManagementClient.deleteTenant(clientId);
+
+    }
+
+
+    @AfterClass(groups = {"tenant-management"})
+    void cleanup() {
+        LOGGER.info("Completing tenant management tests " + LOG_SUFFIX);
+        clientId = null;
+        clientSec = null;
+        serverPort = null;
+        serverHost = null;
+    }
+
+}
diff --git a/custos-tests/src/test/java/org/apache/custos/integration/tests/UserManagementTests.java b/custos-tests/src/test/java/org/apache/custos/integration/tests/UserManagementTests.java
new file mode 100644
index 0000000..0c6e3d4
--- /dev/null
+++ b/custos-tests/src/test/java/org/apache/custos/integration/tests/UserManagementTests.java
@@ -0,0 +1,256 @@
+package org.apache.custos.integration.tests;
+
+import com.google.protobuf.Struct;
+import com.google.protobuf.Value;
+import org.apache.custos.iam.service.*;
+import org.apache.custos.identity.management.client.IdentityManagementClient;
+import org.apache.custos.tenant.manamgement.client.TenantManagementClient;
+import org.apache.custos.user.management.client.UserManagementClient;
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Parameters;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class contains User management tests
+ */
+public class UserManagementTests {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserManagementTests.class);
+
+    private String LOG_SUFFIX = "...........................";
+
+
+    private UserManagementClient userManagementClient;
+    private IdentityManagementClient identityManagementClient;
+    private TenantManagementClient tenantManagementClient;
+
+    private String username;
+
+
+    @Parameters({"server-host", "server-port", "client-id", "client-sec"})
+    @BeforeClass(groups = {"user-management"})
+    public void setup(String serverHost, String serverPort, String clientId, String clientSec) throws IOException {
+        LOGGER.info("Initiating user management test cases  " + LOG_SUFFIX);
+
+        userManagementClient = new UserManagementClient(serverHost, Integer.valueOf(serverPort), clientId, clientSec);
+        identityManagementClient = new IdentityManagementClient(serverHost, Integer.valueOf(serverPort), clientId, clientSec);
+        tenantManagementClient = new TenantManagementClient(serverHost, Integer.valueOf(serverPort), clientId, clientSec);
+
+
+    }
+
+    @Test(groups = {"user-management"})
+    public void registerUser() {
+        LOGGER.info("Executing registerUser test case");
+
+        username = getAlphaNumericString(7);
+
+        RegisterUserResponse response = userManagementClient.
+                registerUser(username, "TestUserF",
+                        "TestUserL", "abcdef",
+                        username + "@gmail.com", false);
+
+        Assert.assertTrue(response.getIsRegistered());
+
+    }
+
+    @Test(groups = {"user-management"}, dependsOnMethods = {"registerUser"})
+    public void enableUser() {
+        LOGGER.info("Executing enableUser test case");
+        UserRepresentation representation = userManagementClient.enableUser(username);
+        OperationStatus status = userManagementClient.isUserEnabled(username);
+        Assert.assertEquals(representation.getFirstName(), "TestUserF");
+        Assert.assertTrue(status.getStatus());
+    }
+
+    @Test(groups = {"user-management"}, dependsOnMethods = {"enableUser"})
+    public void findUser() {
+        LOGGER.info("Executing findUser test case");
+        FindUsersResponse response = userManagementClient.findUser(username,
+                null, null, null, 0, 2);
+        Assert.assertTrue(response.getUsersCount() > 0);
+
+    }
+
+    @Parameters({"admin-username", "admin-password"})
+    @Test(groups = {"user-management"}, dependsOnMethods = {"findUser"})
+    public void addUserAttributes(String adminUsername, String adminPassword) {
+        LOGGER.info("Executing addUserAttributes test case");
+
+        Struct struct = identityManagementClient.getToken(null, null,
+                adminUsername, adminPassword, null, "password");
+        Value value = struct.getFieldsMap().get("access_token");
+        List<String> arrayList = new ArrayList<>();
+        arrayList.add("123456789");
+        UserAttribute attribute = UserAttribute.newBuilder()
+                .setKey("phone")
+                .addAllValues(arrayList)
+                .build();
+        UserAttribute[] attributes = {attribute};
+        String[] users = {username};
+        OperationStatus status = userManagementClient.addUserAttributes(value.getStringValue(), attributes, users);
+        Assert.assertTrue(status.getStatus());
+        UserRepresentation representation = userManagementClient.getUser(username);
+
+        List<UserAttribute> userAttributes = representation.getAttributesList();
+
+        Assert.assertTrue(!userAttributes.isEmpty());
+        boolean attributeAdded = false;
+        for (UserAttribute userAttribute : userAttributes) {
+            if (userAttribute.getKey().equals("phone") && userAttribute.getValuesList().contains("123456789")) {
+                attributeAdded = true;
+            }
+        }
+
+        Assert.assertTrue(attributeAdded);
+
+
+    }
+
+    @Parameters({"admin-username", "admin-password"})
+    @Test(groups = {"user-management"}, dependsOnMethods = {"addUserAttributes"})
+    public void deleteUserAttribute(String adminUsername, String adminPassword) {
+        LOGGER.info("Executing deleteUserAttribute test case");
+        Struct struct = identityManagementClient.getToken(null, null,
+                adminUsername, adminPassword, null, "password");
+        Value value = struct.getFieldsMap().get("access_token");
+        List<String> arrayList = new ArrayList<>();
+        arrayList.add("123456789");
+        UserAttribute attribute = UserAttribute.newBuilder()
+                .setKey("phone")
+                .addAllValues(arrayList)
+                .build();
+        UserAttribute[] attributes = {attribute};
+        String[] users = {username};
+        OperationStatus status = userManagementClient.deleteUserAttributes(value.getStringValue(), attributes, users);
+        Assert.assertTrue(status.getStatus());
+        UserRepresentation representation = userManagementClient.getUser(username);
+
+        List<UserAttribute> userAttributes = representation.getAttributesList();
+
+        boolean attributeDeleted = true;
+        for (UserAttribute userAttribute : userAttributes) {
+            if (userAttribute.getKey().equals("phone") && userAttribute.getValuesList().contains("123456789")) {
+                attributeDeleted = false;
+            }
+        }
+
+        Assert.assertTrue(attributeDeleted);
+
+    }
+
+    @Parameters({"admin-username", "admin-password"})
+    @Test(groups = {"user-management"}, dependsOnMethods = {"deleteUserAttribute"})
+    public void addUserRoles(String adminUsername, String adminPassword) {
+        LOGGER.info("Executing addUserRoles test case");
+
+        Struct struct = identityManagementClient.getToken(null, null,
+                adminUsername, adminPassword, null, "password");
+        Value value = struct.getFieldsMap().get("access_token");
+
+        String[] users = {username};
+        String[] roles = {"testrole"};
+
+        OperationStatus status = userManagementClient.addRolesToUsers(value.getStringValue(), roles, users, false);
+        Assert.assertTrue(status.getStatus());
+        UserRepresentation representation = userManagementClient.getUser(username);
+
+        List<String> realmRolesList = representation.getRealmRolesList();
+        Assert.assertTrue(!realmRolesList.isEmpty());
+        boolean roleAdded = false;
+        for (String role : realmRolesList) {
+            if (role.equals("testrole")) {
+                roleAdded = true;
+            }
+        }
+        Assert.assertTrue(roleAdded);
+
+    }
+
+
+    @Parameters({"admin-username", "admin-password"})
+    @Test(groups = {"user-management"}, dependsOnMethods = {"deleteUserAttribute"})
+    public void deleteUserRoles(String adminUsername, String adminPassword) {
+        LOGGER.info("Executing deleteUserRoles test case");
+        Struct struct = identityManagementClient.getToken(null, null,
+                adminUsername, adminPassword, null, "password");
+        Value value = struct.getFieldsMap().get("access_token");
+
+        String[] roles = {"testrole"};
+
+        OperationStatus status = userManagementClient.deleteUserRoles(value.getStringValue(), new String[0], roles, username);
+        Assert.assertTrue(status.getStatus());
+        UserRepresentation representation = userManagementClient.getUser(username);
+
+        List<String> realmRolesList = representation.getRealmRolesList();
+
+        boolean roleDeleted = true;
+        for (String role : realmRolesList) {
+            if (role.equals("testrole")) {
+                roleDeleted = false;
+            }
+        }
+        Assert.assertTrue(roleDeleted);
+
+    }
+
+    @Parameters({"admin-username", "admin-password"})
+    @Test(groups = {"user-management"}, dependsOnMethods = {"deleteUserRoles"})
+    public void deleteUser(String adminUsername, String adminPassword) {
+        LOGGER.info("Executing deleteUser test case");
+        Struct struct = identityManagementClient.getToken(null, null,
+                adminUsername, adminPassword, null, "password");
+        Value value = struct.getFieldsMap().get("access_token");
+
+        OperationStatus status = userManagementClient.deleteUser(value.getStringValue(), username);
+        Assert.assertTrue(status.getStatus());
+
+    }
+
+
+    @AfterClass(groups = {"user-management"})
+    void cleanup() {
+        LOGGER.info("Completing user management tests " + LOG_SUFFIX);
+        userManagementClient = null;
+        identityManagementClient = null;
+        tenantManagementClient = null;
+
+    }
+
+
+    static String getAlphaNumericString(int n) {
+
+        // chose a Character random from this String
+        String AlphaNumericString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                + "0123456789"
+                + "abcdefghijklmnopqrstuvxyz";
+
+        // create StringBuffer size of AlphaNumericString
+        StringBuilder sb = new StringBuilder(n);
+
+        for (int i = 0; i < n; i++) {
+
+            // generate a random number between
+            // 0 to AlphaNumericString variable length
+            int index
+                    = (int) (AlphaNumericString.length()
+                    * Math.random());
+
+            // add Character one by one in end of sb
+            sb.append(AlphaNumericString
+                    .charAt(index));
+        }
+
+        return sb.toString();
+    }
+
+
+}
diff --git a/custos-tests/src/test/resources/logback.xml b/custos-tests/src/test/resources/logback.xml
new file mode 100644
index 0000000..afaebf8
--- /dev/null
+++ b/custos-tests/src/test/resources/logback.xml
@@ -0,0 +1,14 @@
+<configuration>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <!-- encoders are assigned the type
+             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <root level="info">
+        <appender-ref ref="STDOUT" />
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/custos-tests/src/test/resources/testng.xml b/custos-tests/src/test/resources/testng.xml
new file mode 100644
index 0000000..230b84c
--- /dev/null
+++ b/custos-tests/src/test/resources/testng.xml
@@ -0,0 +1,35 @@
+<suite name="custos integration tests" verbose="2">
+    <test name="custos integration tests">
+        <parameter name="server-host" value="custos.scigap.org"/>
+        <parameter name="server-port" value="31499"/>
+        <parameter name = "client-id" value="custos-yojizqktdk6jiuccn04s-10000504" />
+        <parameter name = "client-sec" value="T7yyBMxdqEtkZ6CINj1Jn5ZU3lgdS0UIlleezeks"/>
+        <parameter name = "admin-username" value="custos@airavata"/>
+        <parameter name="admin-password" value="custos1234"/>
+        <groups>
+            <define name="tenant-management-tests">
+                <include name="tenant-management" />
+            </define>
+            <define name="user-management-tests">
+                <include name="user-management" />
+            </define>
+            <define name="agent-management-tests">
+                <include name="agent-management" />
+            </define>
+            <dependencies>
+                <group depends-on="tenant-management-tests" name="user-management-tests"></group>
+                <group depends-on="user-management-tests" name="agent-management-tests"></group>
+            </dependencies>
+            <run>
+                <include name="tenant-management-tests" />
+                <include name="user-management-tests" />
+                <include name="agent-management-tests" />
+            </run>
+        </groups>
+        <classes>
+            <class name="org.apache.custos.integration.tests.TenantManagementTests" />
+            <class name="org.apache.custos.integration.tests.UserManagementTests" />
+            <class name="org.apache.custos.integration.tests.AgentManagementTests" />
+        </classes>
+    </test>
+</suite>
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/oauth-flow/create.json b/custos-utilities/oidc-scripts/oauth-flow/create.json
new file mode 100644
index 0000000..800f46e
--- /dev/null
+++ b/custos-utilities/oidc-scripts/oauth-flow/create.json
@@ -0,0 +1,4 @@
+{
+  "redirect_uri":"https://idp.htrc.indiana.edu/playground2/*",
+  "code":"6a20ded4-fdbb-4c3f-aa67-81202f3ca161.3c9039d1-7c8f-47cc-8b61-8cf6fcac4204.1a54fdf2-33e0-4e3b-aef9-644f7663c7f0"
+}
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/oauth-flow/setenv.sh b/custos-utilities/oidc-scripts/oauth-flow/setenv.sh
new file mode 100644
index 0000000..2793c38
--- /dev/null
+++ b/custos-utilities/oidc-scripts/oauth-flow/setenv.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# This file contains the environment variables for the service. Set them here and they should
+# get picked up by each script as needed (this assumes everything is being run from the current
+# directory).
+
+# Tip: If you are working with several different clients, you may want to comment out the
+# setting REGISTRATION_URI so it does not get set to what is here.
+
+
+
+export ADMIN_ID=custos/SdRIGO2BH2m0pFI2j8cT/10000001
+export ADMIN_SECRET=YuTa2nMXWzokv45onaktxBvLpFK26Z8hi0rC7rSL
+
+
+export TOKENURI=https://custos.scigap.org:32036/identity-management/v1.0.0/token
+
+# We set the bearer token here so it is available subsequently. This is the least problematic way to
+# do this since it is easy to get the escaping wrong.
+
+#export BEARER_TOKEN=$(echo -n $ADMIN_ID:$ADMIN_SECRET | base64 -w 0)
+export BEARER_TOKEN=Y3VzdG9zL1NkUklHTzJCSDJtMHBGSTJqOGNULzEwMDAwMDAxOll1VGEybk1YV3pva3Y0NW9uYWt0eEJ2THBGSzI2WjhoaTByQzdyU0wK
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/oauth-flow/token.json b/custos-utilities/oidc-scripts/oauth-flow/token.json
new file mode 100644
index 0000000..836b784
--- /dev/null
+++ b/custos-utilities/oidc-scripts/oauth-flow/token.json
@@ -0,0 +1,5 @@
+{
+ "code": 13,
+ "message": "Error occurred while fetching access token for  user 10000001 Code not valid and invalid_grant",
+ "details": []
+}
diff --git a/custos-utilities/oidc-scripts/oauth-flow/token.sh b/custos-utilities/oidc-scripts/oauth-flow/token.sh
new file mode 100644
index 0000000..7dc1b89
--- /dev/null
+++ b/custos-utilities/oidc-scripts/oauth-flow/token.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# A script that performs a cURL call to the custos server that has the client management API enabled on it.
+# This will issue a POST to the endpoint (as per RFC 7591) and will create a new client on the server
+# from the given JSON object.
+# This register an admin client in the Custos and the Custos admin will manually accept the client, once accepted
+# you MUST use the clientId and clientSecret issued in the response for subsequent tenant creations.
+
+source ./setenv.sh
+
+curl -k -X POST -H "Authorization: Bearer $BEARER_TOKEN"  -H "Content-Type: application/json; charset=UTF-8" --data @$1 $TOKENURI > token.json
diff --git a/custos-utilities/oidc-scripts/tenant/activate.json b/custos-utilities/oidc-scripts/tenant/activate.json
new file mode 100644
index 0000000..e5ccada
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/activate.json
@@ -0,0 +1,5 @@
+{
+  "tenantId":10000307,
+  "status":"APPROVED",
+  "updatedBy":"Custos Admin"
+}
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/tenant/create.json b/custos-utilities/oidc-scripts/tenant/create.json
new file mode 100644
index 0000000..ce92e74
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/create.json
@@ -0,0 +1,19 @@
+{
+  "client_name":"sampletenant30",
+  "requester_email":"irjanith@gmail.com",
+  "admin_username":"isjarana",
+  "admin_first_name":"Janith",
+  "admin_last_name":"Ranawaka",
+  "admin_email":"isjarana@iu.edu",
+  "contacts":["+18123915386"],
+  "redirect_uris":["http://tenantsample.com/callback"],
+  "scope":"email",
+  "domain":"tenantsample.com",
+  "admin_password":"1234",
+  "client_uri":"https://custos.lk",
+  "scope":"openId",
+  "domain":"custos.scigap.org",
+  "logo_uri":"https://custos/lk/logo",
+  "application_type":"web",
+  "comment":"Custos For comment"
+}
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/tenant/output_activation.json b/custos-utilities/oidc-scripts/tenant/output_activation.json
new file mode 100644
index 0000000..1fb10fe
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/output_activation.json
@@ -0,0 +1,4 @@
+{
+ "tenantId": "10000307",
+ "status": "APPROVED"
+}
diff --git a/custos-utilities/oidc-scripts/tenant/output_admin.json b/custos-utilities/oidc-scripts/tenant/output_admin.json
new file mode 100644
index 0000000..13aed94
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/output_admin.json
@@ -0,0 +1,10 @@
+{
+  "client_id": "custos/In634rvBEjIWtUHUsjF9/10000307",
+  "client_secret": "GgDv0GiXWsMZeqqQINMiTUtzLX6zpdIMpmkWpsoc",
+  "is_activated": false,
+  "client_id_issued_at": 1580268604000,
+  "client_secret_expires_at": 0,
+  "registration_client_uri": "https://custos.scigap.org:32036/tenant-management/v1.0.0/oauth2/tenant?client_id=custos/In634rvBEjIWtUHUsjF9/10000307",
+  "token_endpoint_auth_method": "client_secret_basic",
+  "msg": "Use Base64 encoded clientId:clientSecret as auth token for authorization, Credentials are activated after admin approval"
+}
diff --git a/custos-utilities/oidc-scripts/tenant/output_delete.json b/custos-utilities/oidc-scripts/tenant/output_delete.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/output_delete.json
@@ -0,0 +1 @@
+{}
diff --git a/custos-utilities/oidc-scripts/tenant/output_get.json b/custos-utilities/oidc-scripts/tenant/output_get.json
new file mode 100644
index 0000000..14fe3ad
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/output_get.json
@@ -0,0 +1,31 @@
+{
+ "client_id": "custos/h9RWrJZTxFoewlVtZf0x/10000308",
+ "client_name": "sampletenant29",
+ "requester_email": "irjanith@gmail.com",
+ "admin_first_name": "Janith",
+ "admin_last_name": "Ranawaka",
+ "admin_email": "isjarana@iu.edu",
+ "contacts": [
+  "+18123915386"
+ ],
+ "redirect_uris": [
+  "http://tenantsample.com/callback"
+ ],
+ "grant_types": [
+  "authorization_code"
+ ],
+ "client_id_issued_at": 1580270498000,
+ "client_uri": "https://custos.lk",
+ "scope": "openId",
+ "domain": "custos.scigap.org",
+ "comment": "Custos For comment",
+ "logo_uri": "https://custos.lk",
+ "application_type": "web",
+ "jwks_uri": "",
+ "example_extension_parameter": "",
+ "tos_uri": "",
+ "policy_uri": "",
+ "jwks": {},
+ "software_id": "",
+ "software_version": ""
+}
diff --git a/custos-utilities/oidc-scripts/tenant/output_tm_creation.json b/custos-utilities/oidc-scripts/tenant/output_tm_creation.json
new file mode 100644
index 0000000..55a605a
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/output_tm_creation.json
@@ -0,0 +1,10 @@
+{
+ "client_id": "custos/h9RWrJZTxFoewlVtZf0x/10000308",
+ "client_secret": "swHWb56grcDFYKZlHqbhw6evtkiaDs7dD2m1aSs1",
+ "is_activated": true,
+ "client_id_issued_at": 1580270498000,
+ "client_secret_expires_at": 0,
+ "registration_client_uri": "https://custos.scigap.org:32036/tenant-management/v1.0.0/oauth2/tenant?client_id=custos/h9RWrJZTxFoewlVtZf0x/10000308",
+ "token_endpoint_auth_method": "client_secret_basic",
+ "msg": "Credentials are activated"
+}
diff --git a/custos-utilities/oidc-scripts/tenant/output_update.json b/custos-utilities/oidc-scripts/tenant/output_update.json
new file mode 100644
index 0000000..bbd3329
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/output_update.json
@@ -0,0 +1,31 @@
+{
+ "client_id": "custos/h9RWrJZTxFoewlVtZf0x/10000308",
+ "client_name": "sampletenant30",
+ "requester_email": "irjanith@gmail.com",
+ "admin_first_name": "Janith",
+ "admin_last_name": "Ranawaka",
+ "admin_email": "isjarana@iu.edu",
+ "contacts": [
+  "+18123915386"
+ ],
+ "redirect_uris": [
+  "http://tenantsample.com/callback"
+ ],
+ "grant_types": [
+  "authorization_code"
+ ],
+ "client_id_issued_at": 1580270498000,
+ "client_uri": "https://custos.lk",
+ "scope": "openId",
+ "domain": "custos.scigap.org",
+ "comment": "Custos For comment",
+ "logo_uri": "https://custos/lk/logo",
+ "application_type": "web",
+ "jwks_uri": "",
+ "example_extension_parameter": "",
+ "tos_uri": "",
+ "policy_uri": "",
+ "jwks": {},
+ "software_id": "",
+ "software_version": ""
+}
diff --git a/custos-utilities/oidc-scripts/tenant/setenv.sh b/custos-utilities/oidc-scripts/tenant/setenv.sh
new file mode 100644
index 0000000..7c1714e
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/setenv.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# This file contains the environment variables for the service. Set them here and they should
+# get picked up by each script as needed (this assumes everything is being run from the current
+# directory).
+
+# Tip: If you are working with several different clients, you may want to comment out the
+# setting REGISTRATION_URI so it does not get set to what is here.
+
+
+export SERVER=https://custos.scigap.org:32036/tenant-management/v1.0.0/oauth2/tenant
+export ACTIVATION_ENDPOINT=https://custos.scigap.org:32036/tenant-management/v1.0.0/status
+export ADMIN_ID=custos/In634rvBEjIWtUHUsjF9/10000307
+export ADMIN_SECRET=GgDv0GiXWsMZeqqQINMiTUtzLX6zpdIMpmkWpsoc
+export REGISTRATION_URI=https://custos.scigap.org:32036/tenant-management/v1.0.0/oauth2/tenant?client_id=custos/h9RWrJZTxFoewlVtZf0x/10000308
+
+# We set the bearer token here so it is available subsequently. This is the least problematic way to
+# do this since it is easy to get the escaping wrong.
+
+#export BEARER_TOKEN=$(echo -n $ADMIN_ID:$ADMIN_SECRET | base64 -w 0)
+export BEARER_TOKEN=Y3VzdG9zL0luNjM0cnZCRWpJV3RVSFVzakY5LzEwMDAwMzA3OkdnRHYwR2lYV3NNWmVxcVFJTk1pVFV0ekxYNnpwZElNcG1rV3Bzb2M=
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/tenant/tm-admin-activation.sh b/custos-utilities/oidc-scripts/tenant/tm-admin-activation.sh
new file mode 100644
index 0000000..3f6596d
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/tm-admin-activation.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# A script that performs a cURL call to the custos server that has the client management API enabled on it.
+# This will issue a POST to the endpoint (as per RFC 7591) and will create a new client on the server
+# from the given JSON object.
+# This register an admin client in the Custos and the Custos admin will manually accept the client, once accepted
+# you MUST use the clientId and clientSecret issued in the response for subsequent tenant creations.
+
+source ./setenv.sh
+
+curl -k -X POST  -H "Content-Type: application/json; charset=UTF-8" --data @$1 $ACTIVATION_ENDPOINT > output_activation.json
+cat output_admin.json
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/tenant/tm-admin-post.sh b/custos-utilities/oidc-scripts/tenant/tm-admin-post.sh
new file mode 100644
index 0000000..a077e6e
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/tm-admin-post.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# A script that performs a cURL call to the custos server that has the client management API enabled on it.
+# This will issue a POST to the endpoint (as per RFC 7591) and will create a new client on the server
+# from the given JSON object.
+# This register an admin client in the Custos and the Custos admin will manually accept the client, once accepted
+# you MUST use the clientId and clientSecret issued in the response for subsequent tenant creations.
+
+source ./setenv.sh
+
+curl -k -X POST  -H "Content-Type: application/json; charset=UTF-8" --data @$1 $SERVER > output_admin.json
+cat output_admin.json
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/tenant/tm-delete.sh b/custos-utilities/oidc-scripts/tenant/tm-delete.sh
new file mode 100644
index 0000000..f3aab43
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/tm-delete.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# A script that performs a cURL call to the custos server that has the client management API enabled on it.
+# This will issue a POST to the endpoint (as per RFC 7591) and will create a new client on the server
+# from the given JSON object.
+# This register an admin client in the Custos and the Custos admin will manually accept the client, once accepted
+# you MUST use the clientId and clientSecret issued in the response for subsequent tenant creations.
+
+source ./setenv.sh
+
+curl -k -X DELETE  -H "Authorization: Bearer $BEARER_TOKEN"  $REGISTRATION_URI > output_delete.json
+cat output_admin.json
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/tenant/tm-get.sh b/custos-utilities/oidc-scripts/tenant/tm-get.sh
new file mode 100644
index 0000000..b220f03
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/tm-get.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# A script that performs a cURL call to the custos server that has the client management API enabled on it.
+# This will issue a POST to the endpoint (as per RFC 7591) and will create a new client on the server
+# from the given JSON object.
+# This register an admin client in the Custos and the Custos admin will manually accept the client, once accepted
+# you MUST use the clientId and clientSecret issued in the response for subsequent tenant creations.
+
+source ./setenv.sh
+
+curl -k -X GET -H "Authorization: Bearer $BEARER_TOKEN" $REGISTRATION_URI > output_get.json
+cat output_admin.json
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/tenant/tm-post.sh b/custos-utilities/oidc-scripts/tenant/tm-post.sh
new file mode 100644
index 0000000..5fa777e
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/tm-post.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# A script that performs a cURL call to the custos server that has the client management API enabled on it.
+# This will issue a POST to the endpoint (as per RFC 7591) and will create a new client on the server
+# from the given JSON object.
+# This register a  tenant under the admin tenant credentials in the Custos and the Custos tenant will be automatically accepted
+
+source ./setenv.sh
+
+curl -k -X POST -H "Authorization: Bearer $BEARER_TOKEN"  -H "Content-Type: application/json; charset=UTF-8" --data @$1 $SERVER > output_tm_creation.json
+cat output_admin.json
\ No newline at end of file
diff --git a/custos-utilities/oidc-scripts/tenant/tm-put.sh b/custos-utilities/oidc-scripts/tenant/tm-put.sh
new file mode 100644
index 0000000..4425dc6
--- /dev/null
+++ b/custos-utilities/oidc-scripts/tenant/tm-put.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# A script that performs a cURL call to the custos server that has the client management API enabled on it.
+# This will issue a POST to the endpoint (as per RFC 7591) and will create a new client on the server
+# from the given JSON object.
+# This register an admin client in the Custos and the Custos admin will manually accept the client, once accepted
+# you MUST use the clientId and clientSecret issued in the response for subsequent tenant creations.
+
+source ./setenv.sh
+
+curl -k -X   PUT -H "Authorization: Bearer $BEARER_TOKEN" -H "Content-Type: application/json; charset=UTF-8" --data @$1 $REGISTRATION_URI > output_update.json
+cat output_admin.json
\ No newline at end of file
diff --git a/custos-utilities/prometheus/prometheus.yml b/custos-utilities/prometheus/prometheus.yml
new file mode 100644
index 0000000..3310434
--- /dev/null
+++ b/custos-utilities/prometheus/prometheus.yml
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+scrape_configs:
+  - job_name: 'prometheus'
+    scrape_interval: 10s
+    static_configs:
+      - targets: ['localhost:9090']
+  - job_name: 'tenantRegistrationService'
+    scrape_interval: 10s
+    metrics_path: '/actuator/prometheus'
+    static_configs:
+      - targets: ['docker.for.mac.localhost:8080']
+
+  - job_name: 'iamAdminCoreService'
+    scrape_interval: 10s
+    metrics_path: '/actuator/prometheus'
+    static_configs:
+        - targets: ['docker.for.mac.localhost:8080']
+
+  - job_name: 'tenantProfileCoreService'
+    scrape_interval: 10s
+    metrics_path: '/actuator/prometheus'
+    static_configs:
+        - targets: ['docker.for.mac.localhost:8080']
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4b810fd
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,533 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>23</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.apache.custos</groupId>
+    <artifactId>custos</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0-SNAPSHOT</version>
+
+    <modules>
+        <module>custos-core-services</module>
+        <module>custos-integration-services</module>
+        <module>custos-core-services-client-stubs</module>
+        <module>custos-integration-core</module>
+        <module>custos-federated-services-clients</module>
+        <module>custos-client-sdks</module>
+        <module>custos-tests</module>
+        <module>custos-external-services-distributions</module>
+    </modules>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-parent</artifactId>
+                <version>${spring.boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-dependencies</artifactId>
+                <version>${spring.cloud.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>io.github.lognet</groupId>
+                <artifactId>grpc-spring-boot-starter</artifactId>
+                <version>${grpc.spring.boot.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>io.grpc</groupId>
+                        <artifactId>grpc-netty</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.springframework.boot</groupId>
+                        <artifactId>spring-boot-starter</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>io.grpc</groupId>
+                <artifactId>grpc-stub</artifactId>
+                <version>${io.grpc.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.grpc</groupId>
+                <artifactId>grpc-protobuf</artifactId>
+                <version>${io.grpc.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.grpc</groupId>
+                <artifactId>grpc-netty</artifactId>
+                <version>${io.grpc.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.annotation</groupId>
+                <artifactId>javax.annotation-api</artifactId>
+                <version>${javax.annotation.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-starter-sleuth</artifactId>
+                <version>${spring.cloud.slueth.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+                <version>${spring.cloud.slueth.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-starter-vault-config</artifactId>
+                <version>${spring.boot.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>io.zipkin.brave</groupId>
+                <artifactId>brave-instrumentation-grpc</artifactId>
+                <version>${brave.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.micrometer</groupId>
+                <artifactId>micrometer-registry-prometheus</artifactId>
+                <version>${io.micrometer.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.google.api.grpc</groupId>
+                <artifactId>proto-google-common-protos</artifactId>
+                <version>${google.common.protos}</version>
+            </dependency>
+            <dependency>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-java</artifactId>
+                <version>${mysql.connector.java}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.persistence</groupId>
+                <artifactId>persistence-api</artifactId>
+                <version>${javax.persistance}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.keycloak</groupId>
+                <artifactId>keycloak-admin-client</artifactId>
+                <version>${keycloak.admin.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.keycloak</groupId>
+                <artifactId>keycloak-authz-client</artifactId>
+                <version>${keycloak.admin.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jboss.resteasy</groupId>
+                <artifactId>resteasy-client</artifactId>
+                <version>${reasteasy.client.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jboss.resteasy</groupId>
+                <artifactId>resteasy-jackson2-provider</artifactId>
+                <version>${reasteasy.client.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jboss.resteasy</groupId>
+                <artifactId>resteasy-jaxrs</artifactId>
+                <version>${reasteasy.client.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jboss.resteasy</groupId>
+                <artifactId>resteasy-multipart-provider</artifactId>
+                <version>${reasteasy.client.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.google.protobuf</groupId>
+                <artifactId>protobuf-java-util</artifactId>
+                <version>${com.google.protobuf.util}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.springfox</groupId>
+                <artifactId>springfox-swagger2</artifactId>
+                <version>${springfox.swagger.version}</version>
+            </dependency>
+
+            <!--Swagger -->
+            <dependency>
+                <groupId>io.springfox</groupId>
+                <artifactId>springfox-swagger-ui</artifactId>
+                <version>${springfox.swagger.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.springfox</groupId>
+                <artifactId>springfox-bean-validators</artifactId>
+                <version>${springfox.swagger.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.xml</groupId>
+                <artifactId>jaxb-api</artifactId>
+                <version>${jaxb.version}</version>
+            </dependency>
+
+            <!-- SCIM-->
+            <dependency>
+                <groupId>org.wso2.charon</groupId>
+                <artifactId>org.wso2.charon3.core</artifactId>
+                <version>${org.wso2.charon}</version>
+            </dependency>
+
+            <!--Kube -->
+            <dependency>
+                <groupId>io.kubernetes</groupId>
+                <artifactId>client-java</artifactId>
+                <version>${kube.java.client.version}</version>
+            </dependency>
+
+
+            <!-- Integration tests dependencies -->
+            <dependency>
+                <groupId>org.testng</groupId>
+                <artifactId>testng</artifactId>
+                <version>${testng.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.json</groupId>
+                <artifactId>json</artifactId>
+                <version>${org.json.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>ch.qos.logback</groupId>
+                <artifactId>logback-classic</artifactId>
+                <version>${log.back.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.jcraft</groupId>
+                <artifactId>jsch</artifactId>
+                <version>${com.jcraft.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>commons-io</groupId>
+                <artifactId>commons-io</artifactId>
+                <version>${io.commons.version}</version>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
+
+    <profiles>
+        <profile>
+            <id>default</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <version>${maven.compiler.plugin}</version>
+                        <executions>
+                            <execution>
+                                <id>default</id>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <release>${java.version}</release>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.springframework.boot</groupId>
+                        <artifactId>spring-boot-maven-plugin</artifactId>
+                        <version>${spring.boot.version}</version>
+                        <executions>
+                            <execution>
+                                <id>default</id>
+                                <goals>
+                                    <goal>repackage</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.xolstice.maven.plugins</groupId>
+                        <artifactId>protobuf-maven-plugin</artifactId>
+                        <version>${protobuf.maven.plugin}</version>
+                        <configuration>
+                            <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}
+                            </protocArtifact>
+                            <pluginId>grpc-java</pluginId>
+                            <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}
+                            </pluginArtifact>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>compile</goal>
+                                    <goal>compile-custom</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>container</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <version>${maven.compiler.plugin}</version>
+                        <executions>
+                            <execution>
+                                <id>container</id>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <release>${java.version}</release>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.springframework.boot</groupId>
+                        <artifactId>spring-boot-maven-plugin</artifactId>
+                        <version>${spring.boot.version}</version>
+                        <executions>
+                            <execution>
+                                <id>container</id>
+                                <goals>
+                                    <goal>repackage</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.xolstice.maven.plugins</groupId>
+                        <artifactId>protobuf-maven-plugin</artifactId>
+                        <version>${protobuf.maven.plugin}</version>
+                        <configuration>
+                            <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}
+                            </protocArtifact>
+                            <pluginId>grpc-java</pluginId>
+                            <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}
+                            </pluginArtifact>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>container</id>
+                                <goals>
+                                    <goal>compile</goal>
+                                    <goal>compile-custom</goal>
+                                    <goal>compile-python</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>com.spotify</groupId>
+                        <artifactId>dockerfile-maven-plugin</artifactId>
+                        <version>${docker.plugin.version}</version>
+                        <executions>
+                            <execution>
+                                <id>container</id>
+                                <goals>
+                                    <goal>build</goal>
+                                    <goal>push</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <noCache>true</noCache>
+                            <serverId>docker.io</serverId>
+                            <repository>${docker.image.prefix}/${project.artifactId}</repository>
+                            <tag>${project.version}</tag>
+                            <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
+                            <buildArgs>
+                                <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
+                            </buildArgs>
+                            <skip>true</skip>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>com.deviceinsight.helm</groupId>
+                        <artifactId>helm-maven-plugin</artifactId>
+                        <version>${helm.maven.plugin.version}</version>
+                        <configuration>
+                            <chartName>${project.artifactId}</chartName>
+                            <chartFolder>src/main/helm</chartFolder>
+                            <chartRepoUrl>https://kubernetes-charts.storage.googleapis.com/</chartRepoUrl>
+                            <helmVersion>2.16.0</helmVersion>
+                            <strictLint>true</strictLint>
+                            <valuesFile>src/main/helm/values.yaml</valuesFile>
+                            <skip>true</skip>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>container</id>
+                                <goals>
+                                    <goal>package</goal>
+                                    <goal>lint</goal>
+                                    <goal>template</goal>
+                                    <goal>deploy</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.rat</groupId>
+                        <artifactId>apache-rat-plugin</artifactId>
+                        <version>${apache.rat.plugin.version}</version>
+                        <configuration>
+                            <excludes>
+                                <exclude>**/*.json</exclude>
+                            </excludes>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>check</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <profile>
+            <id>integration-tests</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <version>${maven.surefile.plugin.version}</version>
+                        <configuration>
+                            <skipTests>true</skipTests>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+                <version>${os.maven.plugin}</version>
+            </extension>
+        </extensions>
+    </build>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <org.slf4j.version>1.7.25</org.slf4j.version>
+        <log4j.version>1.2.17</log4j.version>
+        <thrift.version>0.12.0</thrift.version>
+        <openjpa.version>2.4.3</openjpa.version>
+        <mysql.connector.version>5.1.34</mysql.connector.version>
+        <maven.assembly.plugin>3.3.0</maven.assembly.plugin>
+        <junit.version>4.8.1</junit.version>
+        <jmockit.version>1.8</jmockit.version>
+        <java.version>11</java.version>
+        <javax.annotation.version>1.3.2</javax.annotation.version>
+        <maven.compiler.plugin>3.8.1</maven.compiler.plugin>
+
+        <protobuf.maven.plugin>0.5.1</protobuf.maven.plugin>
+        <os.maven.plugin>1.5.0.Final</os.maven.plugin>
+
+        <!-- Spring dependencies -->
+        <spring.boot.version>2.2.0.RELEASE</spring.boot.version>
+        <spring.cloud.version>Greenwich.RELEASE</spring.cloud.version>
+        <grpc.spring.boot.version>2.4.4</grpc.spring.boot.version>
+
+        <spring.cloud.stream.version>2.0.0.RELEASE</spring.cloud.stream.version>
+        <spring.cloud.slueth.version>2.1.6.RELEASE</spring.cloud.slueth.version>
+
+        <io.grpc.version>1.25.0</io.grpc.version>
+        <google.common.protos>1.17.0</google.common.protos>
+        <io.micrometer.version>1.3.1</io.micrometer.version>
+        <brave.version>5.9.1</brave.version>
+
+        <docker.image.prefix>apachecustos</docker.image.prefix>
+        <docker.image.repo>custos</docker.image.repo>
+        <docker.plugin.version>1.4.13</docker.plugin.version>
+
+        <helm.maven.plugin.version>2.1.0</helm.maven.plugin.version>
+        <maven.assembly.plugin.version>3.2.0</maven.assembly.plugin.version>
+
+        <mysql.connector.java>8.0.18</mysql.connector.java>
+        <javax.persistance>1.0.2</javax.persistance>
+
+        <keycloak.admin.version>7.0.0</keycloak.admin.version>
+
+        <reasteasy.client.version>3.0.14.Final</reasteasy.client.version>
+
+        <com.google.protobuf.util>3.11.3</com.google.protobuf.util>
+
+        <springfox.swagger.version>2.9.2</springfox.swagger.version>
+        <org.wso2.charon>3.3.16</org.wso2.charon>
+        <jaxb.version>2.1</jaxb.version>
+
+        <kube.java.client.version>5.0.0</kube.java.client.version>
+
+        <testng.version>6.8</testng.version>
+        <org.json.version>20190722</org.json.version>
+
+        <apache.rat.plugin.version>0.13</apache.rat.plugin.version>
+
+        <maven.surefile.plugin.version>3.0.0-M4</maven.surefile.plugin.version>
+
+        <log.back.version>1.2.3</log.back.version>
+
+        <com.jcraft.version>0.1.55</com.jcraft.version>
+
+        <io.commons.version>2.7</io.commons.version>
+
+
+    </properties>
+
+</project>
\ No newline at end of file