diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py
index 80988ca84cadea6cb3e2b0f5597b4ae7b9748c6e..9dd3df599312e632c5f3f74ae25c896a9a7a917a 100644
--- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py
+++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py
@@ -3,30 +3,33 @@ from pymongo import ReturnDocument
 import secrets
 import requests
 from .responses import bad_request_error, not_found_error, forbidden_error, internal_server_error, make_response
-from flask import current_app, Flask, Response
+from flask import current_app, Response
 import json
 from datetime import datetime
-from ..util import dict_to_camel_case, clean_empty, serialize_clean_camel_case
+from ..util import dict_to_camel_case, serialize_clean_camel_case
 from .auth_manager import AuthManager
 from .resources import Resource
 from ..config import Config
 from api_invoker_management.models.api_invoker_enrolment_details import APIInvokerEnrolmentDetails
 from .redis_event import RedisEvent
+from .redis_internal_event import RedisInternalEvent
 from .publisher import Publisher
 
 publisher_ops = Publisher()
+
+
 class InvokerManagementOperations(Resource):
 
     def __check_api_invoker_id(self, api_invoker_id):
 
         current_app.logger.debug("Cheking api invoker id")
         mycol = self.db.get_col_by_name(self.db.invoker_enrolment_details)
-        my_query = {'api_invoker_id':api_invoker_id}
+        my_query = {'api_invoker_id': api_invoker_id}
         old_values = mycol.find_one(my_query)
 
         if old_values is None:
             current_app.logger.error("Not found api invoker id")
-            return not_found_error(detail="Please provide an existing Network App ID", cause= "Not exist Network App ID" )
+            return not_found_error(detail="Please provide an existing Network App ID", cause="Not exist Network App ID")
 
         return old_values
 
@@ -35,13 +38,14 @@ class InvokerManagementOperations(Resource):
         url = f"http://{self.config['ca_factory']['url']}:{self.config['ca_factory']['port']}/v1/pki_int/sign/my-ca"
         headers = {'X-Vault-Token': self.config['ca_factory']['token']}
         data = {
-            'format':'pem_bundle',
+            'format': 'pem_bundle',
             'ttl': '43000h',
             'csr': publick_key,
             'common_name': invoker_id
         }
 
-        response = requests.request("POST", url, headers=headers, data=data, verify = self.config["ca_factory"].get("verify", False))
+        response = requests.request("POST", url, headers=headers, data=data,
+                                    verify=self.config["ca_factory"].get("verify", False))
         print(response)
         response_payload = json.loads(response.text)
 
@@ -52,51 +56,59 @@ class InvokerManagementOperations(Resource):
         self.auth_manager = AuthManager()
         self.config = Config().get_config()
 
-
     def add_apiinvokerenrolmentdetail(self, apiinvokerenrolmentdetail, username, uuid):
 
         mycol = self.db.get_col_by_name(self.db.invoker_enrolment_details)
 
-        #try:
+        # try:
         current_app.logger.debug("Creating invoker resource")
-        res = mycol.find_one({'onboarding_information.api_invoker_public_key': apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key})
+        res = mycol.find_one({'onboarding_information.api_invoker_public_key':
+                             apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key})
 
         if res is not None:
-            current_app.logger.error("Generating forbbiden error, invoker registered")
-            return forbidden_error(detail= "Invoker already registered", cause = "Identical invoker public key")
+            current_app.logger.error(
+                "Generating forbbiden error, invoker registered")
+            return forbidden_error(detail="Invoker already registered", cause="Identical invoker public key")
 
         if rfc3987.match(apiinvokerenrolmentdetail.notification_destination, rule="URI") is None:
             current_app.logger.error("Bad url format")
-            return bad_request_error(detail="Bad Param", cause = "Detected Bad formar of param", invalid_params=[{"param": "notificationDestination", "reason": "Not valid URL format"}])
+            return bad_request_error(detail="Bad Param", cause="Detected Bad formar of param", invalid_params=[{"param": "notificationDestination", "reason": "Not valid URL format"}])
 
         current_app.logger.debug("Signing Certificate")
 
         api_invoker_id = 'INV'+str(secrets.token_hex(15))
-        cert = self.__sign_cert(apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, api_invoker_id)
+        cert = self.__sign_cert(
+            apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, api_invoker_id)
 
         apiinvokerenrolmentdetail.api_invoker_id = api_invoker_id
         current_app.logger.debug(cert)
-        apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert['data']['certificate']
+        apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert[
+            'data']['certificate']
 
         # Onboarding Date Record
         invoker_dict = apiinvokerenrolmentdetail.to_dict()
         invoker_dict["onboarding_date"] = datetime.now()
-        invoker_dict["username"]=username
-        invoker_dict["uuid"]=uuid
+        invoker_dict["username"] = username
+        invoker_dict["uuid"] = uuid
 
         mycol.insert_one(invoker_dict)
 
         current_app.logger.debug("Invoker inserted in database")
         current_app.logger.debug("Netapp onboarded sucessfuly")
 
-        self.auth_manager.add_auth_invoker(cert['data']['certificate'], api_invoker_id)
+        self.auth_manager.add_auth_invoker(
+            cert['data']['certificate'], api_invoker_id)
 
-        res = make_response(object=serialize_clean_camel_case(apiinvokerenrolmentdetail), status=201)
-        res.headers['Location'] = "/api-invoker-management/v1/onboardedInvokers/" + str(api_invoker_id)
+        res = make_response(object=serialize_clean_camel_case(
+            apiinvokerenrolmentdetail), status=201)
+        res.headers['Location'] = "/api-invoker-management/v1/onboardedInvokers/" + \
+            str(api_invoker_id)
 
         if res.status_code == 201:
             current_app.logger.info("Invoker Created")
-            RedisEvent("API_INVOKER_ONBOARDED", ["apiInvokerIds"], [[str(api_invoker_id)]]).send_event()
+            RedisEvent("API_INVOKER_ONBOARDED",
+                       ["apiInvokerIds"],
+                       [[str(api_invoker_id)]]).send_event()
         return res
 
     def update_apiinvokerenrolmentdetail(self, onboard_id, apiinvokerenrolmentdetail):
@@ -111,16 +123,23 @@ class InvokerManagementOperations(Resource):
                 return result
 
             if apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key != result["onboarding_information"]["api_invoker_public_key"]:
-                cert = self.__sign_cert(apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, result["api_invoker_id"])
-                apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert['data']['certificate']
-                self.auth_manager.update_auth_invoker(cert['data']["certificate"], onboard_id)
+                cert = self.__sign_cert(
+                    apiinvokerenrolmentdetail.onboarding_information.api_invoker_public_key, result["api_invoker_id"])
+                apiinvokerenrolmentdetail.onboarding_information.api_invoker_certificate = cert[
+                    'data']['certificate']
+                self.auth_manager.update_auth_invoker(
+                    cert['data']["certificate"], onboard_id)
 
             apiinvokerenrolmentdetail_update = apiinvokerenrolmentdetail.to_dict()
             apiinvokerenrolmentdetail_update = {
                 key: value for key, value in apiinvokerenrolmentdetail_update.items() if value is not None
             }
 
-            result = mycol.find_one_and_update(result, {"$set":apiinvokerenrolmentdetail_update}, projection={'_id': 0},return_document=ReturnDocument.AFTER ,upsert=False)
+            result = mycol.find_one_and_update(result,
+                                               {"$set": apiinvokerenrolmentdetail_update},
+                                               projection={'_id': 0},
+                                               return_document=ReturnDocument.AFTER,
+                                               upsert=False)
 
             result = {
                 key: value for key, value in result.items() if value is not None
@@ -130,10 +149,13 @@ class InvokerManagementOperations(Resource):
 
             invoker_updated = APIInvokerEnrolmentDetails().from_dict(dict_to_camel_case(result))
 
-            res = make_response(object=serialize_clean_camel_case(invoker_updated), status=200)
+            res = make_response(object=serialize_clean_camel_case(
+                invoker_updated), status=200)
             if res.status_code == 200:
                 current_app.logger.info("Invoker Updated")
-                RedisEvent("API_INVOKER_UPDATED", ["apiInvokerIds"], [[onboard_id]]).send_event()
+                RedisEvent("API_INVOKER_UPDATED",
+                           ["apiInvokerIds"],
+                           [[onboard_id]]).send_event()
             return res
 
         except Exception as e:
@@ -151,22 +173,26 @@ class InvokerManagementOperations(Resource):
             if isinstance(result, Response):
                 return result
 
-            mycol.delete_one({'api_invoker_id':onboard_id})
+            mycol.delete_one({'api_invoker_id': onboard_id})
             self.auth_manager.remove_auth_invoker(onboard_id)
 
             current_app.logger.debug("Invoker resource removed from database")
             current_app.logger.debug("Netapp offboarded sucessfuly")
-            out =  "The Network App matching onboardingId  " + onboard_id + " was offboarded."
+            out = "The Network App matching onboardingId  " + onboard_id + " was offboarded."
             res = make_response(out, status=204)
             if res.status_code == 204:
                 current_app.logger.info("Invoker Removed")
-                RedisEvent("API_INVOKER_OFFBOARDED", ["apiInvokerIds"], [[onboard_id]]).send_event()
-                publisher_ops.publish_message("internal-messages", f"invoker-removed:{onboard_id}")
+                RedisEvent("API_INVOKER_OFFBOARDED",
+                           ["apiInvokerIds"],
+                           [[onboard_id]]).send_event()
+                RedisInternalEvent("INVOKER-REMOVED",
+                                   "invokerId",
+                                   {
+                                       "api_invoker_id": onboard_id
+                                   }).send_event()
             return res
 
         except Exception as e:
             exception = "An exception occurred in remove invoker"
             current_app.logger.error(exception + "::" + str(e))
             return internal_server_error(detail=exception, cause=str(e))
-
-
diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/consumer_messager.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/consumer_messager.py
index 26f8d6b025229c757bd7e909699c337d02a4a53d..8d5c56f3b71070734d4b9fbabd1f3b81f8d1435c 100644
--- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/consumer_messager.py
+++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/consumer_messager.py
@@ -2,6 +2,8 @@
 import redis
 from .invoker_internal_ops import InvokerInternalOperations
 from flask import current_app
+import json
+
 
 class Subscriber():
 
@@ -14,13 +16,38 @@ class Subscriber():
     def listen(self):
         for raw_message in self.p.listen():
             if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages":
-                message, invoker_id, api_id = raw_message["data"].decode('utf-8').split(":")
-                if message == "security-context-created":
-                    current_app.logger.debug("Internal message received, updating Api list on invoker")
-                    self.invoker_ops.update_services_list(invoker_id, api_id)
-                if message == "security-context-removed":
-                    current_app.logger.debug("Internal message received, removing service in  Api list of invoker")
-                    self.invoker_ops.remove_services_list(invoker_id, api_id)
-
-
-
+                current_app.logger.info("New internal event received")
+                internal_redis_event = json.loads(
+                    raw_message["data"].decode('utf-8'))
+                if internal_redis_event.get('event') == "SECURITY-CONTEXT-CREATED":
+                    current_app.logger.debug(
+                        "Internal message received, updating Api list on invoker")
+                    security_context_information = internal_redis_event.get(
+                        'information', None)
+                    if security_context_information is not None:
+                        api_invoker_id = security_context_information.get(
+                            'api_invoker_id')
+                        api_id = security_context_information.get('api_id')
+                        self.invoker_ops.update_services_list(
+                            api_invoker_id, api_id)
+                elif internal_redis_event.get('event') == "SECURITY-CONTEXT-REMOVED":
+                    current_app.logger.debug(
+                        "Internal message received, removing service in  Api list of invoker")
+                    security_context_information = internal_redis_event.get(
+                        'information', None)
+                    if security_context_information is not None:
+                        api_invoker_id = security_context_information.get(
+                            'api_invoker_id')
+                        api_id = security_context_information.get('api_id')
+                        self.invoker_ops.remove_services_list(
+                            api_invoker_id, api_id)
+                elif internal_redis_event.get('event') == "INVOKER-REMOVED":
+                    api_invoker_id = internal_redis_event.get(
+                        'information', {"api_invoker_id": None}).get('api_invoker_id')
+                    if api_invoker_id is not None:
+                        self.acls_ops.remove_invoker_acl(api_invoker_id)
+                elif internal_redis_event.get('event') == "PROVIDER-REMOVED":
+                    aef_ids = internal_redis_event.get(
+                        'information', {"aef_ids": []}).get('aef_ids')
+                    if len(aef_ids) > 0:
+                        self.acls_ops.remove_provider_acls(aef_ids[0])
diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_internal_event.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_internal_event.py
new file mode 100644
index 0000000000000000000000000000000000000000..faa5ea12cb985b96b3cf8dfb7aaba6136b39e01e
--- /dev/null
+++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_internal_event.py
@@ -0,0 +1,35 @@
+from ..encoder import JSONEncoder
+from .publisher import Publisher
+import json
+
+publisher_ops = Publisher()
+
+
+class RedisInternalEvent():
+    def __init__(self, event, event_detail_key=None, information=None) -> None:
+        self.INTERNAL_MESSAGES = [
+            'INVOKER-REMOVED',
+            'PROVIDER-REMOVED',
+            'SECURITY-CONTEXT-CREATED',
+            'SECURITY-CONTEXT-REMOVED',
+            'create-acl',
+            'remove-acl',
+        ]
+        if event not in self.INTERNAL_MESSAGES:
+            raise Exception(
+                "Internal Message (" + event + ") is not on INTERNAL_MESSAGES enum (" + ','.join(self.INTERNAL_MESSAGES) + ")")
+        self.redis_event = {
+            "event": event
+        }
+        if event_detail_key is not None and information is not None:
+            self.redis_event['key'] = event_detail_key
+            self.redis_event['information'] = information
+
+    def to_string(self):
+        return json.dumps(self.redis_event, cls=JSONEncoder)
+
+    def send_event(self):
+        publisher_ops.publish_message("internal-messages", self.to_string())
+
+    def __call__(self):
+        return self.redis_event
diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py
index 30760b996db7ae7fbbc5fcd212bfaf979dc8a7f2..de8b08f969573f6854a1dedeb4fb3eacddcd7a99 100644
--- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py
+++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py
@@ -10,6 +10,7 @@ from .resources import Resource
 from .auth_manager import AuthManager
 
 from api_provider_management.models.api_provider_enrolment_details import APIProviderEnrolmentDetails  # noqa: E501
+from .redis_internal_event import RedisInternalEvent
 
 
 class ProviderManagementOperations(Resource):
@@ -40,19 +41,24 @@ class ProviderManagementOperations(Resource):
             my_provider_enrolment_details = mycol.find_one(search_filter)
 
             if my_provider_enrolment_details is not None:
-                current_app.logger.error("Found provider registered with same id")
+                current_app.logger.error(
+                    "Found provider registered with same id")
                 return forbidden_error(detail="Provider already registered", cause="Identical provider reg sec")
 
-            api_provider_enrolment_details.api_prov_dom_id = secrets.token_hex(15)
+            api_provider_enrolment_details.api_prov_dom_id = secrets.token_hex(
+                15)
 
             current_app.logger.debug("Generating certs to api prov funcs")
 
             for api_provider_func in api_provider_enrolment_details.api_prov_funcs:
-                api_provider_func.api_prov_func_id = api_provider_func.api_prov_func_role + str(secrets.token_hex(15))
-                certificate = sign_certificate(api_provider_func.reg_info.api_prov_pub_key, api_provider_func.api_prov_func_id)
+                api_provider_func.api_prov_func_id = api_provider_func.api_prov_func_role + \
+                    str(secrets.token_hex(15))
+                certificate = sign_certificate(
+                    api_provider_func.reg_info.api_prov_pub_key, api_provider_func.api_prov_func_id)
                 api_provider_func.reg_info.api_prov_cert = certificate
 
-                self.auth_manager.add_auth_provider(certificate, api_provider_func.api_prov_func_id, api_provider_func.api_prov_func_role, api_provider_enrolment_details.api_prov_dom_id)
+                self.auth_manager.add_auth_provider(certificate, api_provider_func.api_prov_func_id,
+                                                    api_provider_func.api_prov_func_role, api_provider_enrolment_details.api_prov_dom_id)
 
             # Onboarding Date Record
             provider_dict = api_provider_enrolment_details.to_dict()
@@ -61,12 +67,14 @@ class ProviderManagementOperations(Resource):
             provider_dict["uuid"] = uuid
 
             mycol.insert_one(provider_dict)
-            
+
             current_app.logger.debug("Provider inserted in database")
 
-            res = make_response(object=serialize_clean_camel_case(api_provider_enrolment_details), status=201)
+            res = make_response(object=serialize_clean_camel_case(
+                api_provider_enrolment_details), status=201)
 
-            res.headers['Location'] = "/api-provider-management/v1/registrations/" + str(api_provider_enrolment_details.api_prov_dom_id)
+            res.headers['Location'] = "/api-provider-management/v1/registrations/" + \
+                str(api_provider_enrolment_details.api_prov_dom_id)
             return res
 
         except Exception as e:
@@ -84,17 +92,32 @@ class ProviderManagementOperations(Resource):
             if isinstance(result, Response):
                 return result
 
-            apf_id = [ provider_func['api_prov_func_id'] for provider_func in result["api_prov_funcs"] if provider_func['api_prov_func_role'] == 'APF' ]
-            aef_id = [ provider_func['api_prov_func_id'] for provider_func in result["api_prov_funcs"] if provider_func['api_prov_func_role'] == 'AEF' ]
-            amf_id = [ provider_func['api_prov_func_id'] for provider_func in result["api_prov_funcs"] if provider_func['api_prov_func_role'] == 'AMF' ]
+            func_ids = list()
+            for provider_func in result["api_prov_funcs"]:
+                func_ids.append(provider_func['api_prov_func_id'])
+            apf_ids = [provider_func['api_prov_func_id']
+                       for provider_func in result["api_prov_funcs"] if provider_func['api_prov_func_role'] == 'APF']
+            aef_ids = [provider_func['api_prov_func_id']
+                       for provider_func in result["api_prov_funcs"] if provider_func['api_prov_func_role'] == 'AEF']
+            amf_ids = [provider_func['api_prov_func_id']
+                       for provider_func in result["api_prov_funcs"] if provider_func['api_prov_func_role'] == 'AMF']
 
             mycol.delete_one({'api_prov_dom_id': api_prov_dom_id})
-            out =  "The provider matching apiProvDomainId  " + api_prov_dom_id + " was offboarded."
+            out = "The provider matching apiProvDomainId  " + \
+                api_prov_dom_id + " was offboarded."
             current_app.logger.debug("Removed provider domain from database")
 
-            self.auth_manager.remove_auth_provider([apf_id[0], aef_id[0], amf_id[0]])
+            self.auth_manager.remove_auth_provider(func_ids)
+
+            RedisInternalEvent("PROVIDER-REMOVED",
+                               "providerIds",
+                               {
+                                   "apf_ids": apf_ids,
+                                   "aef_ids": aef_ids,
+                                   "amf_ids": amf_ids,
+                                   "all_ids": apf_ids + aef_ids + amf_ids
+                               }).send_event()
 
-            self.publish_ops.publish_message("internal-messages", f"provider-removed:{aef_id[0]}:{apf_id[0]}:{amf_id[0]}")
             return make_response(object=out, status=204)
 
         except Exception as e:
@@ -114,26 +137,33 @@ class ProviderManagementOperations(Resource):
 
             for func in api_provider_enrolment_details.api_prov_funcs:
                 if func.api_prov_func_id is None:
-                    func.api_prov_func_id = func.api_prov_func_role + str(secrets.token_hex(15))
-                    certificate = sign_certificate(func.reg_info.api_prov_pub_key, func.api_prov_func_id)
+                    func.api_prov_func_id = func.api_prov_func_role + \
+                        str(secrets.token_hex(15))
+                    certificate = sign_certificate(
+                        func.reg_info.api_prov_pub_key, func.api_prov_func_id)
                     func.reg_info.api_prov_cert = certificate
 
-                    self.auth_manager.update_auth_provider(certificate, func.api_prov_func_id, api_prov_dom_id, func.api_prov_func_role)
+                    self.auth_manager.update_auth_provider(
+                        certificate, func.api_prov_func_id, api_prov_dom_id, func.api_prov_func_role)
                 else:
                     api_prov_funcs = result["api_prov_funcs"]
                     for api_func in api_prov_funcs:
                         if func.api_prov_func_id == api_func["api_prov_func_id"]:
                             if func.api_prov_func_role != api_func["api_prov_func_role"]:
-                                return bad_request_error(detail="Bad Role in provider", cause="Different role in update reqeuest", invalid_params=[{"param":"api_prov_func_role","reason":"different role with same id"}])
+                                return bad_request_error(detail="Bad Role in provider", cause="Different role in update reqeuest", invalid_params=[{"param": "api_prov_func_role", "reason": "different role with same id"}])
                             if func.reg_info.api_prov_pub_key != api_func["reg_info"]["api_prov_pub_key"]:
-                                certificate = sign_certificate(func.reg_info.api_prov_pub_key, api_func["api_prov_func_id"])
+                                certificate = sign_certificate(
+                                    func.reg_info.api_prov_pub_key, api_func["api_prov_func_id"])
                                 func.reg_info.api_prov_cert = certificate
-                                self.auth_manager.update_auth_provider(certificate, func.api_prov_func_id, api_prov_dom_id, func.api_prov_func_role)
+                                self.auth_manager.update_auth_provider(
+                                    certificate, func.api_prov_func_id, api_prov_dom_id, func.api_prov_func_role)
 
             api_provider_enrolment_details = api_provider_enrolment_details.to_dict()
-            api_provider_enrolment_details = clean_empty(api_provider_enrolment_details)
+            api_provider_enrolment_details = clean_empty(
+                api_provider_enrolment_details)
 
-            result = mycol.find_one_and_update(result, {"$set":api_provider_enrolment_details}, projection={'_id': 0},return_document=ReturnDocument.AFTER ,upsert=False)
+            result = mycol.find_one_and_update(result, {"$set": api_provider_enrolment_details}, projection={
+                                               '_id': 0}, return_document=ReturnDocument.AFTER, upsert=False)
             result = clean_empty(result)
 
             current_app.logger.debug("Provider domain updated in database")
@@ -157,9 +187,11 @@ class ProviderManagementOperations(Resource):
                 return result
 
             api_provider_enrolment_details_patch = api_provider_enrolment_details_patch.to_dict()
-            api_provider_enrolment_details_patch = clean_empty(api_provider_enrolment_details_patch)
+            api_provider_enrolment_details_patch = clean_empty(
+                api_provider_enrolment_details_patch)
 
-            result = mycol.find_one_and_update(result, {"$set":api_provider_enrolment_details_patch}, projection={'_id': 0},return_document=ReturnDocument.AFTER ,upsert=False)
+            result = mycol.find_one_and_update(result, {"$set": api_provider_enrolment_details_patch}, projection={
+                                               '_id': 0}, return_document=ReturnDocument.AFTER, upsert=False)
 
             result = clean_empty(result)
 
@@ -171,4 +203,4 @@ class ProviderManagementOperations(Resource):
         except Exception as e:
             exception = "An exception occurred in patch provider"
             current_app.logger.error(exception + "::" + str(e))
-            return internal_server_error(detail=exception, cause=str(e))
\ No newline at end of file
+            return internal_server_error(detail=exception, cause=str(e))
diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/redis_internal_event.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/redis_internal_event.py
new file mode 100644
index 0000000000000000000000000000000000000000..faa5ea12cb985b96b3cf8dfb7aaba6136b39e01e
--- /dev/null
+++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/redis_internal_event.py
@@ -0,0 +1,35 @@
+from ..encoder import JSONEncoder
+from .publisher import Publisher
+import json
+
+publisher_ops = Publisher()
+
+
+class RedisInternalEvent():
+    def __init__(self, event, event_detail_key=None, information=None) -> None:
+        self.INTERNAL_MESSAGES = [
+            'INVOKER-REMOVED',
+            'PROVIDER-REMOVED',
+            'SECURITY-CONTEXT-CREATED',
+            'SECURITY-CONTEXT-REMOVED',
+            'create-acl',
+            'remove-acl',
+        ]
+        if event not in self.INTERNAL_MESSAGES:
+            raise Exception(
+                "Internal Message (" + event + ") is not on INTERNAL_MESSAGES enum (" + ','.join(self.INTERNAL_MESSAGES) + ")")
+        self.redis_event = {
+            "event": event
+        }
+        if event_detail_key is not None and information is not None:
+            self.redis_event['key'] = event_detail_key
+            self.redis_event['information'] = information
+
+    def to_string(self):
+        return json.dumps(self.redis_event, cls=JSONEncoder)
+
+    def send_event(self):
+        publisher_ops.publish_message("internal-messages", self.to_string())
+
+    def __call__(self):
+        return self.redis_event
diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/consumer_messager.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/consumer_messager.py
index 0da24408e801f22693e0412636df090680c1424c..fef5f8d1ba8e1e453141d10932b212158e692a7c 100644
--- a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/consumer_messager.py
+++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/consumer_messager.py
@@ -3,13 +3,16 @@ import redis
 from config import Config
 from .internal_service_ops import InternalServiceOps
 from flask import current_app
+import json
+
 
 class Subscriber():
 
     def __init__(self):
         self.config = Config().get_config()
-        #set this params using config params
-        self.r = redis.Redis(host=self.config["redis"]["host"], port=self.config["redis"]["port"], db=self.config["redis"]["db"])
+        # set this params using config params
+        self.r = redis.Redis(
+            host=self.config["redis"]["host"], port=self.config["redis"]["port"], db=self.config["redis"]["db"])
         self.acls_ops = InternalServiceOps()
         self.p = self.r.pubsub()
         self.p.subscribe("acls-messages", "internal-messages")
@@ -19,19 +22,24 @@ class Subscriber():
             if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "acls-messages":
                 current_app.logger.info("acls-messages recived")
                 message, *ids = raw_message["data"].decode('utf-8').split(":")
-                if message == "create-acl" and len(ids)==3:
+                if message == "create-acl" and len(ids) == 3:
                     self.acls_ops.create_acl(ids[0], ids[1], ids[2])
-                if message == "remove-acl" and len(ids)==3:
+                if message == "remove-acl" and len(ids) == 3:
                     self.acls_ops.remove_acl(ids[0], ids[1], ids[2])
-                if message == "remove-acl" and len(ids)==1:
-                    self.acls_ops.remove_invoker_acl(ids[0])
-            if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages":
-                message, *ids = raw_message["data"].decode('utf-8').split(":")
-                if message == "invoker-removed" and len(ids)>0:
+                if message == "remove-acl" and len(ids) == 1:
                     self.acls_ops.remove_invoker_acl(ids[0])
-                if message == "provider-removed" or message == "service-removed" and len(ids) > 0:
-                    self.acls_ops.remove_provider_acls(ids[0])
-            
-
-
 
+            if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages":
+                current_app.logger.info("New internal event received")
+                internal_redis_event = json.loads(
+                    raw_message["data"].decode('utf-8'))
+                if internal_redis_event.get('event') == "INVOKER-REMOVED":
+                    api_invoker_id = internal_redis_event.get(
+                        'information', {"api_invoker_id": None}).get('api_invoker_id')
+                    if api_invoker_id is not None:
+                        self.acls_ops.remove_invoker_acl(api_invoker_id)
+                elif internal_redis_event.get('event') == "PROVIDER-REMOVED":
+                    aef_ids = internal_redis_event.get(
+                        'information', {"aef_ids": []}).get('aef_ids')
+                    if len(aef_ids) > 0:
+                        self.acls_ops.remove_provider_acls(aef_ids[0])
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/core/consumer_messager.py b/services/TS29222_CAPIF_Events_API/capif_events/core/consumer_messager.py
index ce6479afb5c3537246cb1b2192709c6e4ed83d8c..c3d095fb6726758b7e61cc551ad5e3a02c9b66bb 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/core/consumer_messager.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/core/consumer_messager.py
@@ -9,6 +9,7 @@ from .notifications import Notifications
 from .internal_event_ops import InternalEventOperations
 from flask import current_app
 
+
 class Subscriber():
 
     def __init__(self):
@@ -23,15 +24,20 @@ class Subscriber():
             current_app.logger.info(raw_message)
             if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "events":
                 current_app.logger.info("Event received")
-                redis_event=json.loads(raw_message["data"].decode('utf-8'))
+                redis_event = json.loads(raw_message["data"].decode('utf-8'))
                 current_app.logger.info(json.dumps(redis_event, indent=4))
                 self.notification.send_notifications(redis_event)
             elif raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages":
-                message, *subscriber_ids = raw_message["data"].decode('utf-8').split(":")
-                if message == "invoker-removed" and len(subscriber_ids)>0:
-                    self.event_ops.delete_all_events(subscriber_ids)
-                if message == "provider-removed" and len(subscriber_ids)>0:
-                    self.event_ops.delete_all_events(subscriber_ids)
-
-
-
+                current_app.logger.info("New internal event received")
+                internal_redis_event = json.loads(
+                    raw_message["data"].decode('utf-8'))
+                if internal_redis_event.get('event') == "INVOKER-REMOVED":
+                    api_invoker_id = internal_redis_event.get(
+                        'information', {"api_invoker_id": None}).get('api_invoker_id')
+                    if api_invoker_id is not None:
+                        self.event_ops.delete_all_events([api_invoker_id])
+                elif internal_redis_event.get('event') == "PROVIDER-REMOVED":
+                    all_ids = internal_redis_event.get(
+                        'information', {"all_ids": None}).get('all_ids')
+                    if all_ids is not None:
+                        self.event_ops.delete_all_events(all_ids)
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py
index 699208bf19690af438d9faa7faa9a948ab462979..193dae4f53601ab7d4380eb7acebc5b186fea946 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py
@@ -1,24 +1,18 @@
-import connexion
-from ..models.service_api_description import ServiceAPIDescription  # noqa: E501
 from ..core.serviceapidescriptions import PublishServiceOperations
+from ..models.service_api_description import ServiceAPIDescription  # noqa: E501
 
-from published_apis.models.problem_details import ProblemDetails  # noqa: E501
-from published_apis.models.service_api_description import ServiceAPIDescription  # noqa: E501
-from published_apis import util
-
-from flask import Response, request, current_app
+from flask import request, current_app
 
 from cryptography import x509
 from cryptography.hazmat.backends import default_backend
 from ..core.validate_user import ControlAccess
 from functools import wraps
-import asyncio
-
 
 service_operations = PublishServiceOperations()
 
 valid_user = ControlAccess()
 
+
 def cert_validation():
     def _cert_validation(f):
         @wraps(f)
@@ -36,8 +30,16 @@ def cert_validation():
 
             if cn != "superadmin":
                 cert_signature = cert.signature.hex()
+                service_api_id = None
+                if 'serviceApiId' in args:
+                    service_api_id = args["serviceApiId"]
                 result = valid_user.validate_user_cert(
-                    args["apfId"], args["serviceApiId"], cert_signature)
+                    args["apfId"], cert_signature, service_api_id)
+
+                if result is not None:
+                    return result
+
+                result = service_operations.check_apf(args["apfId"])
 
                 if result is not None:
                     return result
@@ -47,6 +49,8 @@ def cert_validation():
         return __cert_validation
     return _cert_validation
 
+
+@cert_validation()
 def apf_id_service_apis_get(apf_id):  # noqa: E501
     """apf_id_service_apis_get
 
@@ -63,6 +67,7 @@ def apf_id_service_apis_get(apf_id):  # noqa: E501
     return res
 
 
+@cert_validation()
 def apf_id_service_apis_post(apf_id, body):  # noqa: E501
     """apf_id_service_apis_post
 
@@ -77,20 +82,22 @@ def apf_id_service_apis_post(apf_id, body):  # noqa: E501
     """
     current_app.logger.info("Publishing service")
 
-    supp_feat_dict = ServiceAPIDescription.return_supp_feat_dict(body['supportedFeatures'])
+    supp_feat_dict = ServiceAPIDescription.return_supp_feat_dict(
+        body['supportedFeatures'])
 
     vendor_specific = []
     if request.is_json:
         if supp_feat_dict['VendorExt']:
             aef_profile_array = body['aefProfiles']
-            for (profile,i) in zip(aef_profile_array, range(len(aef_profile_array))):
+            for (profile, i) in zip(aef_profile_array, range(len(aef_profile_array))):
                 for key, val in profile.items():
                     if 'vendorSpecific' in key:
                         vendor_specific.append((i, key, val))
 
         body = ServiceAPIDescription.from_dict(request.get_json())
 
-    res = service_operations.add_serviceapidescription(apf_id, body, vendor_specific)
+    res = service_operations.add_serviceapidescription(
+        apf_id, body, vendor_specific)
 
     return res
 
@@ -114,6 +121,7 @@ def apf_id_service_apis_service_api_id_delete(service_api_id, apf_id):  # noqa:
 
     return res
 
+
 @cert_validation()
 def apf_id_service_apis_service_api_id_get(service_api_id, apf_id):  # noqa: E501
     """apf_id_service_apis_service_api_id_get
@@ -132,6 +140,7 @@ def apf_id_service_apis_service_api_id_get(service_api_id, apf_id):  # noqa: E50
 
     return res
 
+
 @cert_validation()
 def apf_id_service_apis_service_api_id_put(service_api_id, apf_id, body):  # noqa: E501
     """apf_id_service_apis_service_api_id_put
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py
index f781ead9e3beb684bf6face38ef9c0e4fd5cc5bc..2d13802550e9a1a94954bac8f2522a1998767355 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py
@@ -2,6 +2,8 @@
 import redis
 from .internal_service_ops import InternalServiceOps
 from flask import current_app
+import json
+
 
 class Subscriber():
 
@@ -15,10 +17,12 @@ class Subscriber():
         current_app.logger.info("Listening publish messages")
         for raw_message in self.p.listen():
             if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages":
-                message, *ids = raw_message["data"].decode('utf-8').split(":")
-                if message == "provider-removed" and len(ids) > 0:
-                    self.security_ops.delete_intern_service(ids[1])
-
-
-
+                current_app.logger.info("New internal event received")
+                internal_redis_event = json.loads(
+                    raw_message["data"].decode('utf-8'))
+                if internal_redis_event.get('event') == "PROVIDER-REMOVED":
+                    apf_ids = internal_redis_event.get(
+                        'information', {"apf_ids": []}).get('apf_ids')
+                    if len(apf_ids) > 0:
+                        self.security_ops.delete_intern_service(apf_ids)
 
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/internal_service_ops.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/internal_service_ops.py
index 71c2759ddb2faeae4ddefc657055119bda31ee9d..d90174bd54c22837404165be6aa55ff55ad89abf 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/internal_service_ops.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/internal_service_ops.py
@@ -9,14 +9,15 @@ class InternalServiceOps(Resource):
         Resource.__init__(self)
         self.auth_manager = AuthManager()
 
-    def delete_intern_service(self, apf_id):
+    def delete_intern_service(self, apf_ids):
 
         current_app.logger.info("Provider removed, removing services published by APF")
         mycol = self.db.get_col_by_name(self.db.service_api_descriptions)
-        my_query = {'apf_id': apf_id}
-        mycol.delete_many(my_query)
+        for apf_id in apf_ids:
+            my_query = {'apf_id': apf_id}
+            mycol.delete_many(my_query)
 
         #We dont need remove all auth events, because when provider is removed, remove auth entry
         #self.auth_manager.remove_auth_all_service(apf_id)
 
-        current_app.logger.info("Removed service")
\ No newline at end of file
+        current_app.logger.info("Removed service")
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/resources.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/resources.py
index efbe3c2d4cf28cec298ef17b394011dcd6aa66cb..641d4029c98c529e454163cec68c7f625f158c15 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/resources.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/resources.py
@@ -1,7 +1,8 @@
-from abc import ABC, abstractmethod
+from abc import ABC
 from db.db import MongoDatabse
 
+
 class Resource(ABC):
 
     def __init__(self):
-        self.db = MongoDatabse()
\ No newline at end of file
+        self.db = MongoDatabse()
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py
index cddfceaba69f2becd7948b09a0c7928d7e782d78..ef5d4bd79a81507cfd9caf4c765feaecce211ac8 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py
@@ -1,10 +1,10 @@
 from pymongo import ReturnDocument
 import secrets
-from flask import current_app, Flask, Response
+from flask import current_app
 
 from .resources import Resource
 from datetime import datetime
-from ..util import dict_to_camel_case, clean_empty, serialize_clean_camel_case,clean_n_camel_case
+from ..util import dict_to_camel_case, clean_empty, clean_n_camel_case
 from .responses import internal_server_error, forbidden_error, not_found_error, unauthorized_error, make_response
 from .auth_manager import AuthManager
 from .redis_event import RedisEvent
@@ -20,7 +20,7 @@ service_api_not_found_message = "Service API not found"
 
 class PublishServiceOperations(Resource):
 
-    def __check_apf(self, apf_id):
+    def check_apf(self, apf_id):
         providers_col = self.db.get_col_by_name(self.db.capif_provider_col)
 
         current_app.logger.debug("Checking apf id")
@@ -29,13 +29,17 @@ class PublishServiceOperations(Resource):
 
         if provider is None:
             current_app.logger.error("Publisher not exist")
-            return unauthorized_error(detail="Publisher not existing", cause="Publisher id not found")
+            return unauthorized_error(
+                detail="Publisher not existing",
+                cause="Publisher id not found")
 
         list_apf_ids = [func["api_prov_func_id"]
                         for func in provider["api_prov_funcs"] if func["api_prov_func_role"] == "APF"]
         if apf_id not in list_apf_ids:
             current_app.logger.debug("This id not belongs to APF")
-            return unauthorized_error(detail="You are not a publisher", cause="This API is only available for publishers")
+            return unauthorized_error(
+                detail="You are not a publisher",
+                cause="This API is only available for publishers")
 
         return None
 
@@ -51,13 +55,19 @@ class PublishServiceOperations(Resource):
 
             current_app.logger.debug("Geting service apis")
 
-            result = self.__check_apf(apf_id)
-
-            if result != None:
-                return result
-
-            service = mycol.find({"apf_id": apf_id}, {"_id": 0, "api_name": 1, "api_id": 1, "aef_profiles": 1, "description": 1,
-                                 "supported_features": 1, "shareable_info": 1, "service_api_category": 1, "api_supp_feats": 1, "pub_api_path": 1, "ccf_id": 1})
+            service = mycol.find(
+                {"apf_id": apf_id},
+                {"_id": 0,
+                 "api_name": 1,
+                 "api_id": 1,
+                 "aef_profiles": 1,
+                 "description": 1,
+                 "supported_features": 1,
+                 "shareable_info": 1,
+                 "service_api_category": 1,
+                 "api_supp_feats": 1,
+                 "pub_api_path": 1,
+                 "ccf_id": 1})
             current_app.logger.debug(service)
             if service is None:
                 current_app.logger.error("Not found services for this apf id")
@@ -85,12 +95,7 @@ class PublishServiceOperations(Resource):
         mycol = self.db.get_col_by_name(self.db.service_api_descriptions)
 
         try:
-
             current_app.logger.debug("Publishing service")
-            result = self.__check_apf(apf_id)
-
-            if result != None:
-                return result
 
             service = mycol.find_one(
                 {"api_name": serviceapidescription.api_name})
@@ -107,7 +112,7 @@ class PublishServiceOperations(Resource):
             serviceapidescription_dict = serviceapidescription.to_dict()
             if vendor_specific:
                 for vend_spec in vendor_specific:
-                    for (profile,i) in zip(serviceapidescription_dict['aef_profiles'], range(len(serviceapidescription_dict['aef_profiles']))):
+                    for (profile, i) in zip(serviceapidescription_dict['aef_profiles'], range(len(serviceapidescription_dict['aef_profiles']))):
                         if i == vend_spec[0]:
                             profile[vend_spec[1]] = vend_spec[2]
             rec.update(serviceapidescription_dict)
@@ -118,9 +123,10 @@ class PublishServiceOperations(Resource):
 
             current_app.logger.debug("Service inserted in database")
 
-            res = make_response(object=clean_n_camel_case(serviceapidescription_dict), status=201)
+            res = make_response(object=clean_n_camel_case(
+                serviceapidescription_dict), status=201)
             res.headers['Location'] = "http://localhost:8080/published-apis/v1/" + \
-                          str(apf_id) + "/service-apis/" + str(api_id)
+                str(apf_id) + "/service-apis/" + str(api_id)
 
             if res.status_code == 201:
                 current_app.logger.info("Service published")
@@ -128,30 +134,36 @@ class PublishServiceOperations(Resource):
                     if serviceapidescription.supported_features is not None:
                         if serviceapidescription.return_supp_feat_dict(serviceapidescription.supported_features)["ApiStatusMonitoring"]:
                             current_app.logger.info(f"Service available")
-                            RedisEvent("SERVICE_API_AVAILABLE", ["serviceAPIDescriptions", "apiIds"],
-                                    [[clean_n_camel_case(serviceapidescription.to_dict())],[str(api_id)]]).send_event()
+                            RedisEvent("SERVICE_API_AVAILABLE",
+                                       ["serviceAPIDescriptions", "apiIds"],
+                                       [[clean_n_camel_case(serviceapidescription.to_dict())], [str(api_id)]]).send_event()
                         else:
                             current_app.logger.info("Service available")
-                            RedisEvent("SERVICE_API_AVAILABLE", ["apiIds"],
-                                    [str(api_id)]).send_event()
+                            RedisEvent("SERVICE_API_AVAILABLE",
+                                       ["apiIds"],
+                                       [str(api_id)]).send_event()
                     else:
                         current_app.logger.info("Service available")
-                        RedisEvent("SERVICE_API_AVAILABLE", ["apiIds"],
-                                [str(api_id)]).send_event()
+                        RedisEvent("SERVICE_API_AVAILABLE",
+                                   ["apiIds"],
+                                   [str(api_id)]).send_event()
                 else:
                     if serviceapidescription.supported_features is not None:
                         if serviceapidescription.return_supp_feat_dict(serviceapidescription.supported_features)["ApiStatusMonitoring"]:
                             current_app.logger.info(f"Service unavailable")
-                            RedisEvent("SERVICE_API_UNAVAILABLE", ["serviceAPIDescriptions", "apiIds"],
-                                    [[clean_n_camel_case(serviceapidescription.to_dict())],[str(api_id)]]).send_event()
+                            RedisEvent("SERVICE_API_UNAVAILABLE",
+                                       ["serviceAPIDescriptions", "apiIds"],
+                                       [[clean_n_camel_case(serviceapidescription.to_dict())], [str(api_id)]]).send_event()
                         else:
                             current_app.logger.info("Service available")
-                            RedisEvent("SERVICE_API_UNAVAILABLE", ["apiIds"],
-                                    [str(api_id)]).send_event()
+                            RedisEvent("SERVICE_API_UNAVAILABLE",
+                                       ["apiIds"],
+                                       [str(api_id)]).send_event()
                     else:
-                            current_app.logger.info("Service available")
-                            RedisEvent("SERVICE_API_UNAVAILABLE", ["apiIds"],
-                                    [str(api_id)]).send_event()
+                        current_app.logger.info("Service available")
+                        RedisEvent("SERVICE_API_UNAVAILABLE",
+                                   ["apiIds"],
+                                   [str(api_id)]).send_event()
 
             return res
 
@@ -167,17 +179,24 @@ class PublishServiceOperations(Resource):
         try:
             current_app.logger.debug(
                 "Geting service api with id: " + service_api_id)
-            result = self.__check_apf(apf_id)
-
-            if result != None:
-                return result
 
             my_query = {'apf_id': apf_id, 'api_id': service_api_id}
-            service_api = mycol.find_one(my_query, {"_id": 0, "api_name": 1, "api_id": 1, "aef_profiles": 1, "description": 1,
-                                         "supported_features": 1, "shareable_info": 1, "service_api_category": 1, "api_supp_feats": 1, "pub_api_path": 1, "ccf_id": 1})
+            service_api = mycol.find_one(my_query, {"_id": 0,
+                                                    "api_name": 1,
+                                                    "api_id": 1,
+                                                    "aef_profiles": 1,
+                                                    "description": 1,
+                                                    "supported_features": 1,
+                                                    "shareable_info": 1,
+                                                    "service_api_category": 1,
+                                                    "api_supp_feats": 1,
+                                                    "pub_api_path": 1,
+                                                    "ccf_id": 1})
             if service_api is None:
                 current_app.logger.error(service_api_not_found_message)
-                return not_found_error(detail=service_api_not_found_message, cause="No Service with specific credentials exists")
+                return not_found_error(
+                    detail=service_api_not_found_message,
+                    cause="No Service with specific credentials exists")
 
             my_service_api = dict_to_camel_case(service_api)
             my_service_api = clean_empty(my_service_api)
@@ -199,17 +218,16 @@ class PublishServiceOperations(Resource):
 
             current_app.logger.debug(
                 "Removing api service with id: " + service_api_id)
-            result = self.__check_apf(apf_id)
-
-            if result != None:
-                return result
 
             my_query = {'apf_id': apf_id, 'api_id': service_api_id}
-            serviceapidescription_dict = mycol.find_one(my_query, {"_id": 0, "onboarding_date": 0, "apf_id": 0})
+            serviceapidescription_dict = mycol.find_one(
+                my_query, {"_id": 0, "onboarding_date": 0, "apf_id": 0})
 
             if serviceapidescription_dict is None:
                 current_app.logger.error(service_api_not_found_message)
-                return not_found_error(detail="Service API not existing", cause="Service API id not found")
+                return not_found_error(
+                    detail="Service API not existing",
+                    cause="Service API id not found")
 
             mycol.delete_one(my_query)
 
@@ -218,10 +236,12 @@ class PublishServiceOperations(Resource):
             current_app.logger.debug("Removed service from database")
             out = "The service matching api_id " + service_api_id + " was deleted."
             res = make_response(out, status=204)
-            serviceapidescription= clean_empty(dict_to_camel_case(serviceapidescription_dict))
+            serviceapidescription = clean_empty(
+                dict_to_camel_case(serviceapidescription_dict))
             if res.status_code == 204:
                 is_supported = serviceapidescription.get("supportedFeatures") and \
-               ServiceAPIDescription.return_supp_feat_dict(serviceapidescription["supportedFeatures"]).get("ApiStatusMonitoring")
+                    ServiceAPIDescription.return_supp_feat_dict(
+                        serviceapidescription["supportedFeatures"]).get("ApiStatusMonitoring")
 
                 if is_supported:
                     current_app.logger.info("Service unavailable")
@@ -232,7 +252,8 @@ class PublishServiceOperations(Resource):
                     ).send_event()
 
                 else:
-                    status_message = "Service available" if serviceapidescription.get("supportedFeatures") is None else "Service unavailable"
+                    status_message = "Service available" if serviceapidescription.get(
+                        "supportedFeatures") is None else "Service unavailable"
                     current_app.logger.info(status_message)
                     RedisEvent(
                         "SERVICE_API_UNAVAILABLE",
@@ -247,7 +268,9 @@ class PublishServiceOperations(Resource):
             current_app.logger.error(exception + "::" + str(e))
             return internal_server_error(detail=exception, cause=str(e))
 
-    def update_serviceapidescription(self, service_api_id, apf_id, service_api_description):
+    def update_serviceapidescription(self,
+                                     service_api_id, apf_id,
+                                     service_api_description):
 
         mycol = self.db.get_col_by_name(self.db.service_api_descriptions)
 
@@ -256,11 +279,6 @@ class PublishServiceOperations(Resource):
             current_app.logger.debug(
                 "Updating service api with id: " + service_api_id)
 
-            result = self.__check_apf(apf_id)
-
-            if result != None:
-                return result
-
             my_query = {'apf_id': apf_id, 'api_id': service_api_id}
             serviceapidescription = mycol.find_one(my_query)
 
@@ -271,8 +289,21 @@ class PublishServiceOperations(Resource):
             service_api_description = service_api_description.to_dict()
             service_api_description = clean_empty(service_api_description)
 
-            result = mycol.find_one_and_update(serviceapidescription, {"$set": service_api_description}, projection={"_id": 0, "api_name": 1, "api_id": 1, "aef_profiles": 1, "description": 1,
-                                               "supported_features": 1, "shareable_info": 1, "service_api_category": 1, "api_supp_feats": 1, "pub_api_path": 1, "ccf_id": 1}, return_document=ReturnDocument.AFTER, upsert=False)
+            result = mycol.find_one_and_update(
+                serviceapidescription,
+                {"$set": service_api_description},
+                projection={"_id": 0,
+                            "api_name": 1,
+                            "api_id": 1,
+                            "aef_profiles": 1,
+                            "description": 1,
+                            "supported_features": 1,
+                            "shareable_info": 1,
+                            "service_api_category": 1,
+                            "api_supp_feats": 1,
+                            "pub_api_path": 1,
+                            "ccf_id": 1},
+                return_document=ReturnDocument.AFTER, upsert=False)
 
             result = clean_empty(result)
 
@@ -282,40 +313,46 @@ class PublishServiceOperations(Resource):
 
             response = make_response(
                 object=service_api_description_updated, status=200)
-            
-            service_api_description = ServiceAPIDescription.from_dict(json.dumps(service_api_description_updated, cls=CustomJSONEncoder))
+
+            service_api_description = ServiceAPIDescription.from_dict(
+                json.dumps(service_api_description_updated, cls=CustomJSONEncoder))
             if response.status_code == 200:
                 RedisEvent("SERVICE_API_UPDATE", ["serviceAPIDescriptions"], [[
                            service_api_description_updated]]).send_event()
-                if service_api_description.api_status  is None or len(service_api_description.api_status.aef_ids) > 0:
+                if service_api_description.api_status is None or len(service_api_description.api_status.aef_ids) > 0:
                     if service_api_description.supported_features is not None:
                         if service_api_description.return_supp_feat_dict(service_api_description.supported_features)["ApiStatusMonitoring"]:
                             current_app.logger.info(f"Service available")
-                            RedisEvent("SERVICE_API_AVAILABLE", ["serviceAPIDescriptions", "apiIds"],
-                                    [[service_api_description],[str(service_api_id)]]).send_event()
+                            RedisEvent("SERVICE_API_AVAILABLE",
+                                       ["serviceAPIDescriptions", "apiIds"],
+                                       [[service_api_description], [str(service_api_id)]]).send_event()
                         else:
                             current_app.logger.info("Service available")
-                            RedisEvent("SERVICE_API_AVAILABLE", ["apiIds"],
-                                    [str(service_api_id)]).send_event()
+                            RedisEvent("SERVICE_API_AVAILABLE",
+                                       ["apiIds"],
+                                       [str(service_api_id)]).send_event()
                     else:
-                            current_app.logger.info("Service available")
-                            RedisEvent("SERVICE_API_AVAILABLE", ["apiIds"],
-                                    [str(service_api_id)]).send_event()
+                        current_app.logger.info("Service available")
+                        RedisEvent("SERVICE_API_AVAILABLE", 
+                                   ["apiIds"],
+                                   [str(service_api_id)]).send_event()
                 else:
                     if service_api_description.supported_features is not None:
                         if service_api_description.return_supp_feat_dict(service_api_description.supported_features)["ApiStatusMonitoring"]:
                             current_app.logger.info(f"Service unavailable")
-                            RedisEvent("SERVICE_API_UNAVAILABLE", ["serviceAPIDescriptions", "apiIds"],
-                                    [[service_api_description],[str(service_api_id)]]).send_event()
+                            RedisEvent("SERVICE_API_UNAVAILABLE",
+                                       ["serviceAPIDescriptions", "apiIds"],
+                                       [[service_api_description], [str(service_api_id)]]).send_event()
                         else:
                             current_app.logger.info("Service available")
-                            RedisEvent("SERVICE_API_UNAVAILABLE", ["apiIds"],
-                                    [str(service_api_id)]).send_event()
+                            RedisEvent("SERVICE_API_UNAVAILABLE",
+                                       ["apiIds"],
+                                       [str(service_api_id)]).send_event()
                     else:
-                            current_app.logger.info("Service available")
-                            RedisEvent("SERVICE_API_UNAVAILABLE", ["apiIds"],
-                                    [str(service_api_id)]).send_event()
-                    
+                        current_app.logger.info("Service available")
+                        RedisEvent("SERVICE_API_UNAVAILABLE",
+                                   ["apiIds"],
+                                   [str(service_api_id)]).send_event()
 
             return response
 
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/validate_user.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/validate_user.py
index e73cf8a8c856a064ecbb6b31536521b3bbcca026..9d0c69ca88f765d40e48b353b74f9d1cf9eadf76 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/validate_user.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/validate_user.py
@@ -9,21 +9,39 @@ from ..util import serialize_clean_camel_case
 
 class ControlAccess(Resource):
 
-    def validate_user_cert(self, apf_id, service_id, cert_signature):
+    def validate_user_cert(self, apf_id, cert_signature, service_id=None):
 
         cert_col = self.db.get_col_by_name(self.db.certs_col)
 
         try:
-            my_query = {'id':apf_id}
+            my_query = {'id': apf_id}
             cert_entry = cert_col.find_one(my_query)
 
             if cert_entry is not None:
-                if cert_entry["cert_signature"] != cert_signature or "services" not in cert_entry["resources"] or service_id not in cert_entry["resources"]["services"]:
-                    prob = ProblemDetails(title="Unauthorized", detail="User not authorized", cause="You are not the owner of this resource")
+                is_user_owner = True
+                if cert_entry["cert_signature"] != cert_signature:
+                    is_user_owner = False
+                elif service_id:
+                    if "services" not in cert_entry["resources"]:
+                        is_user_owner = False
+                    elif cert_entry.get("resources") and cert_entry["resources"].get("services"):
+                        if service_id not in cert_entry["resources"].get("services"):
+                            is_user_owner = False
+                if is_user_owner == False:
+                    current_app.logger.info("STEP3")
+                    prob = ProblemDetails(
+                        title="Unauthorized",
+                        detail="User not authorized",
+                        cause="You are not the owner of this resource")
+                    current_app.logger.info("STEP4")
                     prob = serialize_clean_camel_case(prob)
-                    return Response(json.dumps(prob, cls=CustomJSONEncoder), status=401, mimetype="application/json")
+                    current_app.logger.info("STEP5")
+                    return Response(
+                        json.dumps(prob, cls=CustomJSONEncoder),
+                        status=401,
+                        mimetype="application/json")
 
         except Exception as e:
             exception = "An exception occurred in validate apf"
             current_app.logger.error(exception + "::" + str(e))
-            return internal_server_error(detail=exception, cause=str(e))
\ No newline at end of file
+            return internal_server_error(detail=exception, cause=str(e))
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py
index 643dda4f7a96c4e663d6aac3fd956ba0797bb39b..3885c5894ec0dde63d0e5f0593a9d35270f5cb22 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/db/db.py
@@ -13,6 +13,13 @@ if monitoring_value == "true":
 
 class MongoDatabse():
 
+    # _instance = None
+
+    # def __new__(cls):
+    #     if cls._instance is None:
+    #         cls._instance = super(MongoDatabse, cls).__new__(cls)
+    #     return cls._instance
+
     def __init__(self):
         self.config = Config().get_config()
         self.db = self.__connect()
@@ -20,7 +27,6 @@ class MongoDatabse():
         self.capif_provider_col = self.config['mongo']['capif_provider_col']
         self.certs_col = self.config['mongo']['certs_col']
 
-
     def get_col_by_name(self, name):
         return self.db[name].with_options(codec_options=CodecOptions(tz_aware=True))
 
diff --git a/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py b/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py
index d56b02c71619bc920ad8acb1095699bbf518f3d3..eec268a656a32e7138817824f555074ccc214a96 100644
--- a/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py
+++ b/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py
@@ -1,15 +1,6 @@
-import connexion
-from typing import Dict
-from typing import Tuple
-from typing import Union
-
-from capif_security.models.access_token_err import AccessTokenErr  # noqa: E501
-from capif_security.models.access_token_rsp import AccessTokenRsp  # noqa: E501
-from capif_security.models.problem_details import ProblemDetails  # noqa: E501
 from capif_security.models.res_owner_id import ResOwnerId  # noqa: E501
 from capif_security.models.security_notification import SecurityNotification  # noqa: E501
 from capif_security.models.service_security import ServiceSecurity  # noqa: E501
-from capif_security import util
 
 from cryptography import x509
 from cryptography.hazmat.backends import default_backend
@@ -20,13 +11,16 @@ from ..core.publisher import Publisher
 
 from ..core.servicesecurity import SecurityOperations
 
-from flask import Response, request, current_app
+from flask import request, current_app
+
+from ..core.redis_internal_event import RedisInternalEvent
 
 service_security_ops = SecurityOperations()
 publish_ops = Publisher()
 
 valid_user = ControlAccess()
 
+
 def cert_validation():
     def _cert_validation(f):
         @wraps(f)
@@ -36,17 +30,21 @@ def cert_validation():
             cert_tmp = request.headers['X-Ssl-Client-Cert']
             cert_raw = cert_tmp.replace('\t', '')
 
-            cert = x509.load_pem_x509_certificate(str.encode(cert_raw), default_backend())
+            cert = x509.load_pem_x509_certificate(
+                str.encode(cert_raw), default_backend())
 
-            cn = cert.subject.get_attributes_for_oid(x509.OID_COMMON_NAME)[0].value.strip()
+            cn = cert.subject.get_attributes_for_oid(
+                x509.OID_COMMON_NAME)[0].value.strip()
             current_app.logger.info(f"CN: {cn}")
-            if cn != "superadmin" and "AEF" not in cn :
+            if cn != "superadmin" and "AEF" not in cn:
                 cert_signature = cert.signature.hex()
 
                 if "securityId" in args:
-                    result = valid_user.validate_user_cert(args["securityId"], cert_signature)
+                    result = valid_user.validate_user_cert(
+                        args["securityId"], cert_signature)
                 else:
-                    result = valid_user.validate_user_cert(args["apiInvokerId"], cert_signature)
+                    result = valid_user.validate_user_cert(
+                        args["apiInvokerId"], cert_signature)
 
                 if result is not None:
                     return result
@@ -56,6 +54,7 @@ def cert_validation():
         return __cert_validation
     return _cert_validation
 
+
 @cert_validation()
 def securities_security_id_token_post(security_id, body):  # noqa: E501
     """securities_security_id_token_post
@@ -84,7 +83,7 @@ def securities_security_id_token_post(security_id, body):  # noqa: E501
     current_app.logger.info("Creating security token")
     if request.is_json:
         res_owner_id = ResOwnerId.from_dict(request.get_json())  # noqa: E501
-    
+
     # body={"security_id": security_id,
     #       "grant_type": grant_type,
     #       "client_id": client_id,
@@ -95,12 +94,12 @@ def securities_security_id_token_post(security_id, body):  # noqa: E501
     #       "redirect_uri": redirect_uri
     #     }
     current_app.logger.debug(body)
-    
-    res = service_security_ops.return_token(security_id, body)
 
+    res = service_security_ops.return_token(security_id, body)
 
     return res
 
+
 @cert_validation()
 def trusted_invokers_api_invoker_id_delete(api_invoker_id):  # noqa: E501
     """trusted_invokers_api_invoker_id_delete
@@ -115,6 +114,7 @@ def trusted_invokers_api_invoker_id_delete(api_invoker_id):  # noqa: E501
     current_app.logger.info("Removing security context")
     return service_security_ops.delete_servicesecurity(api_invoker_id)
 
+
 @cert_validation()
 def trusted_invokers_api_invoker_id_delete_post(api_invoker_id, body):  # noqa: E501
     """trusted_invokers_api_invoker_id_delete_post
@@ -134,9 +134,10 @@ def trusted_invokers_api_invoker_id_delete_post(api_invoker_id, body):  # noqa:
 
     current_app.logger.info("Revoking permissions")
     res = service_security_ops.revoke_api_authorization(api_invoker_id, body)
-    
+
     return res
 
+
 @cert_validation()
 def trusted_invokers_api_invoker_id_get(api_invoker_id, authentication_info=None, authorization_info=None):  # noqa: E501
     """trusted_invokers_api_invoker_id_get
@@ -153,10 +154,12 @@ def trusted_invokers_api_invoker_id_get(api_invoker_id, authentication_info=None
     :rtype: Union[ServiceSecurity, Tuple[ServiceSecurity, int], Tuple[ServiceSecurity, int, Dict[str, str]]
     """
     current_app.logger.info("Obtaining security context")
-    res = service_security_ops.get_servicesecurity(api_invoker_id, authentication_info, authorization_info)
+    res = service_security_ops.get_servicesecurity(
+        api_invoker_id, authentication_info, authorization_info)
 
     return res
 
+
 @cert_validation()
 def trusted_invokers_api_invoker_id_put(api_invoker_id, body):  # noqa: E501
     """trusted_invokers_api_invoker_id_put
@@ -179,10 +182,16 @@ def trusted_invokers_api_invoker_id_put(api_invoker_id, body):  # noqa: E501
     if res.status_code == 201:
         for service_instance in body.security_info:
             if service_instance.api_id is not None:
-                publish_ops.publish_message("internal-messages", "security-context-created:"+api_invoker_id+":"+service_instance.api_id )
+                RedisInternalEvent("SECURITY-CONTEXT-CREATED",
+                                   "securityIds",
+                                   {
+                                       "api_invoker_id": api_invoker_id,
+                                       "api_id": service_instance.api_id
+                                   }).send_event()
 
     return res
 
+
 @cert_validation()
 def trusted_invokers_api_invoker_id_update_post(api_invoker_id, body):  # noqa: E501
     """trusted_invokers_api_invoker_id_update_post
diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py b/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py
index 43445583236a5743ea1475079a3c329bb0788787..5a90b3eea15655cec2432af72d4320cd534e1487 100644
--- a/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py
+++ b/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py
@@ -2,6 +2,7 @@
 import redis
 from .internal_security_ops import InternalSecurityOps
 from flask import current_app
+import json
 
 
 class Subscriber():
@@ -16,8 +17,15 @@ class Subscriber():
         current_app.logger.info("Listening security context messages")
         for raw_message in self.p.listen():
             if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages":
-                message, *ids = raw_message["data"].decode('utf-8').split(":")
-                if message == "invoker-removed" and len(ids) > 0:
-                    self.security_ops.delete_intern_servicesecurity(ids[0])
-                if message == "provider-removed" or message == "service-removed" and len(ids) > 0:
-                    self.security_ops.update_intern_servicesecurity(ids[0])
+                internal_redis_event = json.loads(
+                    raw_message["data"].decode('utf-8'))
+                if internal_redis_event.get('event') == "INVOKER-REMOVED":
+                    api_invoker_id = internal_redis_event.get(
+                        'information', {"api_invoker_id": None}).get('api_invoker_id')
+                    if api_invoker_id is not None:
+                        self.security_ops.delete_intern_servicesecurity(api_invoker_id)
+                elif internal_redis_event.get('event') == "PROVIDER-REMOVED":
+                    aef_ids = internal_redis_event.get(
+                        'information', {"aef_ids": []}).get("aef_ids")
+                    if len(aef_ids) > 0:
+                        self.security_ops.update_intern_servicesecurity(aef_ids)
diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/internal_security_ops.py b/services/TS29222_CAPIF_Security_API/capif_security/core/internal_security_ops.py
index d1b28d5938fa8f7c1d2c5d2bf9d4a3a9b3c68fda..1f0871017571b7967291e424822aee522192fb3e 100644
--- a/services/TS29222_CAPIF_Security_API/capif_security/core/internal_security_ops.py
+++ b/services/TS29222_CAPIF_Security_API/capif_security/core/internal_security_ops.py
@@ -1,6 +1,7 @@
 
 from .resources import Resource
 
+
 class InternalSecurityOps(Resource):
 
     def delete_intern_servicesecurity(self, api_invoker_id):
@@ -9,13 +10,16 @@ class InternalSecurityOps(Resource):
         my_query = {'api_invoker_id': api_invoker_id}
         mycol.delete_many(my_query)
 
-    def update_intern_servicesecurity(self, id):
+    def update_intern_servicesecurity(self, ids):
 
         security_col = self.db.get_col_by_name(self.db.security_info)
-
-        security_contexts = security_col.find({"$or":[{"security_info.aef_id":id}, {"security_info.api_id":id}]})
-
-        for security_context in security_contexts:
-            new_security_info = [info for info  in security_context["security_info"] if info["aef_id"]!=id and info["api_id"] != id]
-            security_context["security_info"] = new_security_info
-            security_col.update_one({'api_invoker_id':security_context["api_invoker_id"]}, {"$set":security_context})
+        for id in ids:
+            security_contexts = security_col.find(
+                {"$or": [{"security_info.aef_id": id}, {"security_info.api_id": id}]})
+
+            for security_context in security_contexts:
+                new_security_info = [info for info in security_context["security_info"]
+                                     if info["aef_id"] != id and info["api_id"] != id]
+                security_context["security_info"] = new_security_info
+                security_col.update_one({'api_invoker_id': security_context["api_invoker_id"]}, {
+                                        "$set": security_context})
diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/redis_internal_event.py b/services/TS29222_CAPIF_Security_API/capif_security/core/redis_internal_event.py
new file mode 100644
index 0000000000000000000000000000000000000000..faa5ea12cb985b96b3cf8dfb7aaba6136b39e01e
--- /dev/null
+++ b/services/TS29222_CAPIF_Security_API/capif_security/core/redis_internal_event.py
@@ -0,0 +1,35 @@
+from ..encoder import JSONEncoder
+from .publisher import Publisher
+import json
+
+publisher_ops = Publisher()
+
+
+class RedisInternalEvent():
+    def __init__(self, event, event_detail_key=None, information=None) -> None:
+        self.INTERNAL_MESSAGES = [
+            'INVOKER-REMOVED',
+            'PROVIDER-REMOVED',
+            'SECURITY-CONTEXT-CREATED',
+            'SECURITY-CONTEXT-REMOVED',
+            'create-acl',
+            'remove-acl',
+        ]
+        if event not in self.INTERNAL_MESSAGES:
+            raise Exception(
+                "Internal Message (" + event + ") is not on INTERNAL_MESSAGES enum (" + ','.join(self.INTERNAL_MESSAGES) + ")")
+        self.redis_event = {
+            "event": event
+        }
+        if event_detail_key is not None and information is not None:
+            self.redis_event['key'] = event_detail_key
+            self.redis_event['information'] = information
+
+    def to_string(self):
+        return json.dumps(self.redis_event, cls=JSONEncoder)
+
+    def send_event(self):
+        publisher_ops.publish_message("internal-messages", self.to_string())
+
+    def __call__(self):
+        return self.redis_event
diff --git a/services/run_capif_tests.sh b/services/run_capif_tests.sh
index 1ad4d973112a0daf16fe0dbc6f26d45062d16d4c..65749bf3f9514fae2ead580962777a1292a0cf76 100755
--- a/services/run_capif_tests.sh
+++ b/services/run_capif_tests.sh
@@ -18,8 +18,7 @@ CAPIF_HTTPS_PORT=443
 # VAULT access configuration
 CAPIF_VAULT=vault
 CAPIF_VAULT_PORT=8200
-CAPIF_VAULT_TOKEN=read-ca-token
-
+CAPIF_VAULT_TOKEN=dev-only-token
 
 MOCK_SERVER_URL=http://mock-server:9100
 NOTIFICATION_DESTINATION_URL=http://mock-server:9100
diff --git a/tests/features/CAPIF Api Provider Management/capif_api_provider_management.robot b/tests/features/CAPIF Api Provider Management/capif_api_provider_management.robot
index 9e4d81e29e2f5c96176e457995e572757053d0ea..bda73735c2bd023f1abc3bbfba4c73e40eff31c4 100644
--- a/tests/features/CAPIF Api Provider Management/capif_api_provider_management.robot	
+++ b/tests/features/CAPIF Api Provider Management/capif_api_provider_management.robot	
@@ -19,7 +19,7 @@ Register Api Provider
     [Tags]    capif_api_provider_management-1
     # Register Provider User An create Certificates for each function
     ${register_user_info}=    Register User At Jwt Auth Provider
-    ...    username=${PROVIDER_USERNAME}    role=${PROVIDER_ROLE}
+    ...    username=${PROVIDER_USERNAME}
 
     # Create provider Registration Body
     ${apf_func_details}=    Create Api Provider Function Details
diff --git a/tests/features/CAPIF Api Publish Service/capif_api_publish_service.robot b/tests/features/CAPIF Api Publish Service/capif_api_publish_service.robot
index 5df5c4cf29be197ab6f2eed2653e41fb0468648d..8808e7deb5efaabfbf900bc55f73dd29e179548a 100644
--- a/tests/features/CAPIF Api Publish Service/capif_api_publish_service.robot	
+++ b/tests/features/CAPIF Api Publish Service/capif_api_publish_service.robot	
@@ -16,7 +16,7 @@ ${SERVICE_API_ID_NOT_VALID}     not-valid
 
 *** Test Cases ***
 Publish API by Authorised API Publisher
-    [Tags]    capif_api_publish_service-1  smoke
+    [Tags]    capif_api_publish_service-1    smoke
     # Register APF
     ${register_user_info}=    Provider Default Registration
 
@@ -284,10 +284,10 @@ Delete API Published by Authorised apfId with valid serviceApiId
     ...    verify=ca.crt
     ...    username=${APF_PROVIDER_USERNAME}
 
-    Check Response Variable Type And Values    ${resp}    401    ProblemDetails
-    ...    title=Unauthorized
-    ...    detail=User not authorized
-    ...    cause=You are not the owner of this resource
+    Check Response Variable Type And Values    ${resp}    404    ProblemDetails
+    ...    title=Not Found
+    ...    detail=Service API not found
+    ...    cause=No Service with specific credentials exists
 
 Delete APIs Published by Authorised apfId with invalid serviceApiId
     [Tags]    capif_api_publish_service-12
@@ -324,3 +324,72 @@ Delete APIs Published by NON Authorised apfId
     ...    status=401
     ...    detail=User not authorized
     ...    cause=Certificate not authorized
+
+Check Two Published APIs with different APFs are removed when Provider is deleted
+    [Tags]    capif_api_publish_service-14
+    # Register APF with 2 APF roles
+    ${register_user_info}=    Provider Default Registration    total_apf_roles=2
+
+    # Publish APIs with both APFs
+    ${service_api_description_published_1}    ${resource_url}    ${request_body}=    Publish Service Api
+    ...    ${register_user_info}
+    ...    service_1
+    ${service_api_description_published_2}    ${resource_url}    ${request_body}=    Publish Service Api
+    ...    ${register_user_info}
+    ...    service_2
+    ...    apf_username=${APF_PROVIDER_USERNAME}_1
+
+    # Store apiId1
+    ${serviceApiId1}=    Set Variable    ${service_api_description_published_1['apiId']}
+    ${serviceApiId2}=    Set Variable    ${service_api_description_published_2['apiId']}
+
+    # Retrieve Service1
+    ${resp}=    Get Request Capif
+    ...    /published-apis/v1/${register_user_info['apf_id']}/service-apis/${serviceApiId1}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${APF_PROVIDER_USERNAME}
+
+    Check Response Variable Type And Values    ${resp}    200    ServiceAPIDescription
+    Dictionaries Should Be Equal    ${resp.json()}    ${service_api_description_published_1}
+
+    # Retrieve Service2
+    ${resp}=    Get Request Capif
+    ...    /published-apis/v1/${register_user_info['apf_roles']['${APF_PROVIDER_USERNAME}_1']['apf_id']}/service-apis/${serviceApiId2}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${APF_PROVIDER_USERNAME}_1
+
+    Check Response Variable Type And Values    ${resp}    200    ServiceAPIDescription
+    Dictionaries Should Be Equal    ${resp.json()}    ${service_api_description_published_2}
+
+    # Get all services present at CCF
+    ${services_present_on_ccf_after_publish}=    Get Number Of Services
+
+    # Delete Provider using AMF cert
+    ${resp}=    Delete Request Capif
+    ...    ${register_user_info['resource_url'].path}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${AMF_PROVIDER_USERNAME}
+
+    Call Method    ${CAPIF_USERS}    remove_capif_users_entry    ${register_user_info['resource_url'].path}
+
+    ${services_present_on_ccf_after_delete_provider}=    Get Number Of Services
+
+    ${services_removed}=   Evaluate    ${services_present_on_ccf_after_publish} - ${services_present_on_ccf_after_delete_provider}
+
+    Run Keyword And Continue On Failure    Should Be Equal    "${services_removed}"    "2"      msg=Not all services removed after delete provider (removed) vs (expected)
+
+    # Remove service API by superadmin
+    ${resp}=    Delete Request Capif
+    ...    /published-apis/v1/${register_user_info['apf_roles']['${APF_PROVIDER_USERNAME}_1']['apf_id']}/service-apis/${serviceApiId2}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${SUPERADMIN_USERNAME}
+
+    ${services_present_on_ccf_after_provider_deletion_superadmin}=    Get Number Of Services
+
+    ${services_removed}=   Evaluate    ${services_present_on_ccf_after_publish} - ${services_present_on_ccf_after_provider_deletion_superadmin}
+    
+    Run Keyword And Continue On Failure   Should Be Equal    "${services_removed}"    "2"      msg=Not all services removed after delete provider (removed) vs (expected)
diff --git a/tests/features/CAPIF Security Api/capif_security_api.robot b/tests/features/CAPIF Security Api/capif_security_api.robot
index eb2d725a3aaf9fc0f55095de2deeab6ada4f5164..85b26ee335bc29def3b8054701dfc42dfaf121f5 100644
--- a/tests/features/CAPIF Security Api/capif_security_api.robot	
+++ b/tests/features/CAPIF Security Api/capif_security_api.robot	
@@ -835,7 +835,6 @@ Retrieve access token with invalid client_id
 
 Retrieve access token with unsupported grant_type
     [Tags]    capif_security_api-24
-    Skip    Test ${TEST_NAME} is not currently supported by CAPIF
     # Default Invoker Registration and Onboarding
     # Register APF
     ${register_user_info_provider}=    Provider Default Registration
@@ -890,9 +889,10 @@ Retrieve access token with unsupported grant_type
     Check Response Variable Type And Values
     ...    ${resp}
     ...    400
-    ...    AccessTokenErr
-    ...    error=unsupported_grant_type
-    ...    error_description=Invalid value for `grant_type` \\(${grant_type}\\), must be one of \\['client_credentials'\\] - 'grant_type'
+    ...    ProblemDetails
+    ...    title=Bad Request
+    ...    detail='not_valid' is not one of \\['client_credentials', 'authorization_code'\\] - 'grant_type'
+    ...    status=400
 
 Retrieve access token with invalid scope
     [Tags]    capif_security_api-25
diff --git a/tests/features/__init__.robot b/tests/features/__init__.robot
index 19e0fdb7e68b094801d11ec7f563450fa5029a0b..3ac73ab8898640e7a1040fe8d9603d55b30fa3c6 100644
--- a/tests/features/__init__.robot
+++ b/tests/features/__init__.robot
@@ -45,6 +45,8 @@ Prepare environment
     END
     # Obtain ca root certificate
     Retrieve Ca Root
+    
+    Retrieve Superadmin Cert
 
     Reset Testing Environment
 
@@ -54,3 +56,12 @@ Retrieve Ca Root
     Status Should Be    200    ${resp}
     Log    ${resp.json()['data']['data']['ca']}
     Store In File    ca.crt    ${resp.json()['data']['data']['ca']}
+
+Retrieve Superadmin Cert
+    [Documentation]    This keyword retrieve ca.root from CAPIF and store it at ca.crt in order to use at TLS communications
+    ${resp}=    Obtain Superadmin Cert From Vault  /v1/pki_int/sign/my-ca  ${CAPIF_HTTP_VAULT_URL}
+    Status Should Be    200    ${resp}
+    Log Dictionary    ${resp.json()}
+    Log    ${resp.json()['data']['certificate']}
+    Store In File    ${SUPERADMIN_USERNAME}.crt    ${resp.json()['data']['certificate']}
+
diff --git a/tests/libraries/bodyRequests.py b/tests/libraries/bodyRequests.py
index 4790e5457a71124812f2ebbc0b88761e77737aae..450ca5ae2a24503e07a8fe436bf79c46e2796be5 100644
--- a/tests/libraries/bodyRequests.py
+++ b/tests/libraries/bodyRequests.py
@@ -6,4 +6,4 @@ from api_events.bodyRequests import *
 from security_api.bodyRequests import *
 from api_provider_management.bodyRequests import *
 from vendor_extensibility.bodyRequests import *
-from vault_requests.bodyRequests import *
\ No newline at end of file
+from vault_requests.bodyRequests import *
diff --git a/tests/libraries/common/bodyRequests.py b/tests/libraries/common/bodyRequests.py
index b0829b7231cc34863e7abd15e8a8422edf1d1ee2..e87f3492a711b922d776459f10667ea27d91c80b 100644
--- a/tests/libraries/common/bodyRequests.py
+++ b/tests/libraries/common/bodyRequests.py
@@ -1,4 +1,3 @@
-from operator import contains
 import re
 import json
 from xmlrpc.client import boolean
@@ -141,3 +140,13 @@ def check_regex(input, regex):
         return True
     else:
         raise Exception("Input(" + input + ") not match regex (" + regex + ")")
+
+
+def vault_sign_superadmin_certificate_body(csr_request):
+    data = {
+        'format': 'pem_bundle',
+        'ttl': '43000h',
+        'csr': csr_request,
+        'common_name': "superadmin"
+    }
+    return data
diff --git a/tests/libraries/helpers.py b/tests/libraries/helpers.py
index c7806f15fa4dc5155495794e009ca8b782dbf06b..1b974f2d743368fe3379e6c3f58f3bda8248e229 100644
--- a/tests/libraries/helpers.py
+++ b/tests/libraries/helpers.py
@@ -1,13 +1,10 @@
-import requests
 import re
-import pandas as pd
 from urllib.parse import urlparse
 from OpenSSL.crypto import (dump_certificate_request, dump_privatekey,
                             PKey, TYPE_RSA, X509Req)
 from OpenSSL.SSL import FILETYPE_PEM
 import socket
 import copy
-import json
 import pickle
 
 
@@ -142,23 +139,45 @@ def create_scope(aef_id, api_name):
 
     return data
 
+
 def read_dictionary(file_path):
     with open(file_path, 'rb') as fp:
         data = pickle.load(fp)
         print('Dictionary loaded')
         return data
 
+
 def write_dictionary(file_path, data):
     with open(file_path, 'wb') as fp:
         pickle.dump(data, fp)
         print('dictionary saved successfully to file ' + file_path)
 
+
 def filter_users_by_prefix_username(users, prefix):
     if prefix.strip() == "":
         raise Exception('prefix value must contain some value')
 
-    filtered_users=list()
+    filtered_users = list()
     for user in users:
         if user['username'].startswith(prefix):
             filtered_users.append(user['username'])
     return filtered_users
+
+
+def sign_csr_body(username, public_key):
+    data = {
+        "csr":  public_key.decode("utf-8"),
+        "mode":  "client",
+        "filename": username
+    }
+    return data
+
+
+def vault_sign_superadmin_certificate_body(csr_request):
+    data = {
+        "format": "pem_bundle",
+        "ttl": "43000h",
+        "csr": csr_request.decode("utf-8"),
+        "common_name": "superadmin"
+    }
+    return data
diff --git a/tests/resources/common.resource b/tests/resources/common.resource
index 0acd867808cd86832d3ae299cf5f5ada7d7b20d7..d5cc35eb293202e616eceb614aad8083d6089394 100644
--- a/tests/resources/common.resource
+++ b/tests/resources/common.resource
@@ -8,6 +8,7 @@ Resource        /opt/robot-tests/tests/resources/common/basicRequests.robot
 
 
 *** Variables ***
+${SUPERADMIN_USERNAME}          ROBOT_TESTING_SUPERADMIN
 ${INVOKER_USERNAME}             ROBOT_TESTING_INVOKER
 ${PROVIDER_USERNAME}            ROBOT_TESTING_PROVIDER
 ${APF_PROVIDER_USERNAME}        APF_${PROVIDER_USERNAME}
diff --git a/tests/resources/common/basicRequests.robot b/tests/resources/common/basicRequests.robot
index b5c08c0d6f07bb4451521fe4ad15c2e5518e62a5..5327f397f662961e45e25bc1e0920e613a791fe0 100644
--- a/tests/resources/common/basicRequests.robot
+++ b/tests/resources/common/basicRequests.robot
@@ -6,7 +6,8 @@ Library             Collections
 Library             OperatingSystem
 Library             XML
 Library             Telnet
-Library    String
+Library             String
+
 
 
 *** Variables ***
@@ -85,7 +86,7 @@ Create Register Admin Session
 ## NEW REQUESTS TO REGISTER
 
 Post Request Admin Register
-    [Timeout]  ${REQUESTS_TIMEOUT}
+    [Timeout]    ${REQUESTS_TIMEOUT}
     [Arguments]
     ...    ${endpoint}
     ...    ${json}=${NONE}
@@ -115,7 +116,7 @@ Post Request Admin Register
     RETURN    ${resp}
 
 Get Request Admin Register
-    [Timeout]  ${REQUESTS_TIMEOUT}
+    [Timeout]    ${REQUESTS_TIMEOUT}
     [Arguments]
     ...    ${endpoint}
     ...    ${server}=${NONE}
@@ -149,7 +150,7 @@ Delete User Admin Register Request
 # NEW REQUESTS END
 
 Post Request Capif
-    [Timeout]  ${REQUESTS_TIMEOUT}
+    [Timeout]    ${REQUESTS_TIMEOUT}
     [Arguments]
     ...    ${endpoint}
     ...    ${json}=${NONE}
@@ -179,7 +180,7 @@ Post Request Capif
     RETURN    ${resp}
 
 Get Request Capif
-    [Timeout]  ${REQUESTS_TIMEOUT}
+    [Timeout]    ${REQUESTS_TIMEOUT}
     [Arguments]
     ...    ${endpoint}
     ...    ${server}=${NONE}
@@ -205,7 +206,7 @@ Get Request Capif
     RETURN    ${resp}
 
 Get CA Vault
-    [Timeout]  ${REQUESTS_TIMEOUT}
+    [Timeout]    ${REQUESTS_TIMEOUT}
     [Arguments]
     ...    ${endpoint}
     ...    ${server}=${NONE}
@@ -229,10 +230,39 @@ Get CA Vault
     ...    verify=${verify}
     ...    cert=${cert}
     RETURN    ${resp}
-    RETURN    ${response}
+
+Obtain Superadmin Cert From Vault
+    [Timeout]    ${REQUESTS_TIMEOUT}
+    [Arguments]
+    ...    ${endpoint}
+    ...    ${server}=${NONE}
+    ...    ${access_token}=${NONE}
+    ...    ${auth}=${NONE}
+    ...    ${verify}=${FALSE}
+    ...    ${cert}=${NONE}
+    ...    ${username}=${NONE}
+
+    ${headers}=    Create CAPIF Session    ${server}    ${access_token}    vault_token=${CAPIF_VAULT_TOKEN}
+
+    IF    '${username}' != '${NONE}'
+        ${cert}=    Set variable    ${{ ('${username}.crt','${username}.key') }}
+    END
+
+    ${csr_request}=    Create User Csr    ${SUPERADMIN_USERNAME}    cn=superadmin
+    ${json}=    Vault Sign Superadmin Certificate Body    ${csr_request}
+
+    ${resp}=    Post On Session
+    ...    apisession
+    ...    ${endpoint}
+    ...    json=${json}
+    ...    headers=${headers}
+    ...    expected_status=any
+    ...    verify=${verify}
+    ...    cert=${cert}
+    RETURN    ${resp}
 
 Put Request Capif
-    [Timeout]  ${REQUESTS_TIMEOUT}
+    [Timeout]    ${REQUESTS_TIMEOUT}
     [Arguments]
     ...    ${endpoint}
     ...    ${json}=${NONE}
@@ -261,7 +291,7 @@ Put Request Capif
     RETURN    ${resp}
 
 Patch Request Capif
-    [Timeout]  ${REQUESTS_TIMEOUT}
+    [Timeout]    ${REQUESTS_TIMEOUT}
     [Arguments]
     ...    ${endpoint}
     ...    ${json}=${NONE}
@@ -274,7 +304,7 @@ Patch Request Capif
 
     ${headers}=    Create CAPIF Session    ${server}    ${access_token}
 
-    Set To Dictionary 	${headers} 	Content-Type 	application/merge-patch+json
+    Set To Dictionary    ${headers}    Content-Type    application/merge-patch+json
 
     IF    '${username}' != '${NONE}'
         ${cert}=    Set variable    ${{ ('${username}.crt','${username}.key') }}
@@ -292,7 +322,7 @@ Patch Request Capif
     RETURN    ${resp}
 
 Delete Request Capif
-    [Timeout]  ${REQUESTS_TIMEOUT}
+    [Timeout]    ${REQUESTS_TIMEOUT}
     [Arguments]
     ...    ${endpoint}
     ...    ${server}=${NONE}
@@ -367,19 +397,65 @@ Register User At Jwt Auth
     RETURN    ${register_user_info}
 
 Register User At Jwt Auth Provider
-    [Arguments]    ${username}    ${role}    ${password}=password    ${description}=Testing
+    [Arguments]
+    ...    ${username}
+    ...    ${password}=password
+    ...    ${description}=Testing
+    ...    ${total_apf_roles}=1
+    ...    ${total_aef_roles}=1
+    ...    ${total_amf_roles}=1
+
+    ${apf_roles}=    Create Dictionary
+    ${default_apf_username}=    Set Variable    APF_${username}
+    FOR    ${index}    IN RANGE    ${total_apf_roles}
+        ${apf_username}=    Set Variable    ${default_apf_username}_${index}
+        IF    ${index} == 0
+            ${apf_username}=    Set Variable    ${default_apf_username}
+        END
+        ${apf_csr_request}=    Create User Csr    ${apf_username}    apf
+        ${apf_role}=
+        ...    Create Dictionary
+        ...    username=${apf_username}
+        ...    csr_request=${apf_csr_request}
+        ...    role=APF
+        Set To Dictionary    ${apf_roles}    ${apf_username}=${apf_role}
+    END
 
-    ${apf_username}=    Set Variable    APF_${username}
-    ${aef_username}=    Set Variable    AEF_${username}
-    ${amf_username}=    Set Variable    AMF_${username}
+    ${aef_roles}=    Create Dictionary
+    ${default_aef_username}=    Set Variable    AEF_${username}
+    FOR    ${index}    IN RANGE    ${total_aef_roles}
+        ${aef_username}=    Set Variable    ${default_aef_username}_${index}
+        IF    ${index} == 0
+            ${aef_username}=    Set Variable    ${default_aef_username}
+        END
+        ${aef_csr_request}=    Create User Csr    ${aef_username}    aef
+        ${aef_role}=
+        ...    Create Dictionary
+        ...    username=${aef_username}
+        ...    csr_request=${aef_csr_request}
+        ...    role=AEF
+        Set To Dictionary    ${aef_roles}    ${aef_username}=${aef_role}
+    END
+
+    ${amf_roles}=    Create Dictionary
+    ${default_amf_username}=    Set Variable    AMF_${username}
+    FOR    ${index}    IN RANGE    ${total_amf_roles}
+        ${amf_username}=    Set Variable    ${default_amf_username}_${index}
+        IF    ${index} == 0
+            ${amf_username}=    Set Variable    ${default_amf_username}
+        END
+        ${amf_csr_request}=    Create User Csr    ${amf_username}    amf
+        ${amf_role}=
+        ...    Create Dictionary
+        ...    username=${amf_username}
+        ...    csr_request=${amf_csr_request}
+        ...    role=AMF
+        Set To Dictionary    ${amf_roles}    ${amf_username}=${amf_role}
+    END
 
     # Create a certificate for each kind of role under provider
     ${csr_request}=    Create User Csr    ${username}    provider
 
-    ${apf_csr_request}=    Create User Csr    ${apf_username}    apf
-    ${aef_csr_request}=    Create User Csr    ${aef_username}    aef
-    ${amf_csr_request}=    Create User Csr    ${amf_username}    amf
-
     # Register provider
     ${resp}=    Create User At Register
     ...    ${username}
@@ -394,12 +470,15 @@ Register User At Jwt Auth Provider
     ${register_user_info}=    Create Dictionary
     ...    netappID=${resp.json()['uuid']}
     ...    csr_request=${csr_request}
-    ...    apf_csr_request=${apf_csr_request}
-    ...    aef_csr_request=${aef_csr_request}
-    ...    amf_csr_request=${amf_csr_request}
-    ...    apf_username=${apf_username}
-    ...    aef_username=${aef_username}
-    ...    amf_username=${amf_username}
+    ...    apf_username=${default_apf_username}
+    ...    aef_username=${default_aef_username}
+    ...    amf_username=${default_amf_username}
+    ...    apf_csr_request=${apf_roles['${default_apf_username}']['csr_request']}
+    ...    aef_csr_request=${aef_roles['${default_aef_username}']['csr_request']}
+    ...    amf_csr_request=${amf_roles['${default_amf_username}']['csr_request']}
+    ...    apf_roles=${apf_roles}
+    ...    aef_roles=${aef_roles}
+    ...    amf_roles=${amf_roles}
     ...    &{resp.json()}
     ...    &{get_auth_response}
 
@@ -439,18 +518,18 @@ Delete User At Register
     [Documentation]    (Administrator) This Keyword delete a user from register.
     [Arguments]    ${username}=${NONE}    ${uuid}=${NONE}
     ${user_uuid}=    Set Variable    ${uuid}
-    ${environment_users}=   Set Variable   ${TRUE}
+    ${environment_users}=    Set Variable    ${TRUE}
 
     IF    "${username}" != "${NONE}"
         ${user_uuid}=    Call Method    ${CAPIF_USERS}    get_user_uuid    ${username}
     END
 
-    IF   "${user_uuid}" == "${NONE}"
-        ${user_uuid}=   Get User Uuid At Register    ${username}
-        ${environment_users}=   Set Variable   ${FALSE}
+    IF    "${user_uuid}" == "${NONE}"
+        ${user_uuid}=    Get User Uuid At Register    ${username}
+        ${environment_users}=    Set Variable    ${FALSE}
     END
 
-    ${resp}=    Delete User Admin Register Request   ${user_uuid}
+    ${resp}=    Delete User Admin Register Request    ${user_uuid}
 
     Should Be Equal As Strings    ${resp.status_code}    204
 
@@ -473,23 +552,22 @@ Get List of Users At Register
 Get User Uuid At Register
     [Documentation]    (Administrator) This Keyword retrieve a list of users and search uuid of user passed by parameters
     [Arguments]    ${username}
-    ${users}=   Get List of Users At Register
+    ${users}=    Get List of Users At Register
 
     # Find the first user with username indicated
     ${user_uuid}=    Set Variable    &{EMPTY}
-    FOR    ${user}   IN   @{users}
-        IF   "${user['username']}" == "${username}"
-            ${user_uuid}=    Set Variable   ${user['uuid']}
+    FOR    ${user}    IN    @{users}
+        IF    "${user['username']}" == "${username}"
+            ${user_uuid}=    Set Variable    ${user['uuid']}
             BREAK
         END
     END
 
-    IF   "${user_uuid}" == "${EMPTY}"
+    IF    "${user_uuid}" == "${EMPTY}"
         Log    ${username} not found in Register
     END
-    
-    RETURN  ${user_uuid}    
 
+    RETURN    ${user_uuid}
 
 Get Auth For User
     [Documentation]    (User) This Keyword retrieve token to be used by user towards first interaction with CCF.
@@ -567,7 +645,7 @@ Remove Resource
     ...    verify=ca.crt
     ...    username=${management_cert}
 
-    Run Keyword and Continue On Failure   Status Should Be    204    ${resp}
+    Run Keyword and Continue On Failure    Status Should Be    204    ${resp}
 
     Delete User At Register    username=${username}
 
@@ -611,20 +689,16 @@ Invoker Default Onboarding
 Provider Registration
     [Arguments]    ${register_user_info}
 
+    ${api_prov_funcs}=    Create List
+
     # Create provider Registration Body
-    ${apf_func_details}=    Create Api Provider Function Details
-    ...    ${register_user_info['apf_username']}
-    ...    ${register_user_info['apf_csr_request']}
-    ...    APF
-    ${aef_func_details}=    Create Api Provider Function Details
-    ...    ${register_user_info['aef_username']}
-    ...    ${register_user_info['aef_csr_request']}
-    ...    AEF
-    ${amf_func_details}=    Create Api Provider Function Details
-    ...    ${register_user_info['amf_username']}
-    ...    ${register_user_info['amf_csr_request']}
-    ...    AMF
-    ${api_prov_funcs}=    Create List    ${apf_func_details}    ${aef_func_details}    ${amf_func_details}
+    FOR    ${key}    ${value}    IN    &{register_user_info['apf_roles']}    &{register_user_info['aef_roles']}    &{register_user_info['amf_roles']}
+        ${func_details}=    Create Api Provider Function Details
+        ...    ${key}
+        ...    ${value['csr_request']}
+        ...    ${value['role']}
+        Append To List    ${api_prov_funcs}    ${func_details}
+    END
 
     ${request_body}=    Create Api Provider Enrolment Details Body
     ...    ${register_user_info['access_token']}
@@ -647,12 +721,29 @@ Provider Registration
     FOR    ${prov}    IN    @{resp.json()['apiProvFuncs']}
         Log Dictionary    ${prov}
         Store In File    ${prov['apiProvFuncInfo']}.crt    ${prov['regInfo']['apiProvCert']}
+        Log Dictionary   ${register_user_info}
+        Log  ${register_user_info['apf_username']}
         IF    "${prov['apiProvFuncRole']}" == "APF"
-            Set To Dictionary    ${register_user_info}    apf_id=${prov['apiProvFuncId']}
+            IF    "${prov['apiProvFuncInfo']}" == "${register_user_info['apf_username']}"
+                Set To Dictionary    ${register_user_info}    apf_id=${prov['apiProvFuncId']}
+            END
+            Set To Dictionary
+            ...    ${register_user_info['apf_roles']['${prov['apiProvFuncInfo']}']}
+            ...    apf_id=${prov['apiProvFuncId']}
         ELSE IF    "${prov['apiProvFuncRole']}" == "AEF"
-            Set To Dictionary    ${register_user_info}    aef_id=${prov['apiProvFuncId']}
+            IF    "${prov['apiProvFuncInfo']}" == "${register_user_info['aef_username']}"
+                Set To Dictionary    ${register_user_info}    aef_id=${prov['apiProvFuncId']}
+            END
+            Set To Dictionary
+            ...    ${register_user_info['aef_roles']['${prov['apiProvFuncInfo']}']}
+            ...    aef_id=${prov['apiProvFuncId']}
         ELSE IF    "${prov['apiProvFuncRole']}" == "AMF"
-            Set To Dictionary    ${register_user_info}    amf_id=${prov['apiProvFuncId']}
+            IF    "${prov['apiProvFuncInfo']}" == "${register_user_info['amf_username']}"
+                Set To Dictionary    ${register_user_info}    amf_id=${prov['apiProvFuncId']}
+            END
+            Set To Dictionary
+            ...    ${register_user_info['amf_roles']['${prov['apiProvFuncInfo']}']}
+            ...    amf_id=${prov['apiProvFuncId']}
         ELSE
             Fail    "${prov['apiProvFuncRole']} is not valid role"
         END
@@ -674,10 +765,20 @@ Provider Registration
     RETURN    ${register_user_info}
 
 Provider Default Registration
-    [Arguments]    ${provider_username}=${PROVIDER_USERNAME}
+    [Arguments]    
+    ...    ${provider_username}=${PROVIDER_USERNAME}
+    ...    ${total_apf_roles}=1
+    ...    ${total_aef_roles}=1
+    ...    ${total_amf_roles}=1
+    ...    ${apf_id}=${NONE}
+    ...    ${apf_username}=${NONE}
+
     # Register Provider
     ${register_user_info}=    Register User At Jwt Auth Provider
-    ...    username=${provider_username}    role=${PROVIDER_ROLE}
+    ...    username=${provider_username}
+    ...    total_apf_roles=${total_apf_roles}
+    ...    total_aef_roles=${total_aef_roles}
+    ...    total_amf_roles=${total_amf_roles}
 
     ${register_user_info}=    Provider Registration    ${register_user_info}
 
@@ -686,15 +787,37 @@ Provider Default Registration
     RETURN    ${register_user_info}
 
 Publish Service Api
-    [Arguments]    ${register_user_info_provider}    ${service_name}=service_1    ${supported_features}=fffff    ${vendor_specific_service_api_description}=${None}   ${vendor_specific_aef_profile}=${None}
+    [Arguments]
+    ...    ${register_user_info_provider}
+    ...    ${service_name}=service_1
+    ...    ${apf_id}=${NONE}
+    ...    ${apf_username}=${NONE}
+    ...    ${supported_features}=fffff
+    ...    ${vendor_specific_service_api_description}=${None}
+    ...    ${vendor_specific_aef_profile}=${None}
+
+    ${apf_id_to_use}=    Set Variable    ${register_user_info_provider['apf_id']}
+    ${apf_username_to_use}=    Set Variable    ${register_user_info_provider['apf_username']}
+    IF    "${apf_id}" != "${NONE}" and "${apf_id}" != "${register_user_info_provider['apf_id']}"
+        FOR    ${apf_username}    ${apf_role}    IN    &{register_user_info_provider['apf_roles']}
+            IF    "${apf_role['apf_id']}" == "${apf_id}"
+                ${apf_id_to_use}=    Set Variable    ${apf_id}
+                ${apf_username_to_use}=    Set Variable    ${apf_username}
+                BREAK
+            END
+        END
+    ELSE IF    "${apf_username}" != "${NONE}" and "${apf_username}" != "${register_user_info_provider['apf_username']}"
+        ${apf_id_to_use}=    Set Variable    ${register_user_info_provider['apf_roles']['${apf_username}']['apf_id']}
+        ${apf_username_to_use}=    Set Variable    ${apf_username}
+    END
 
     ${request_body}=    Create Service Api Description    ${service_name}    ${register_user_info_provider['aef_id']}  ${supported_features}  ${vendor_specific_service_api_description}   ${vendor_specific_aef_profile}
     ${resp}=    Post Request Capif
-    ...    /published-apis/v1/${register_user_info_provider['apf_id']}/service-apis
+    ...    /published-apis/v1/${apf_id_to_use}/service-apis
     ...    json=${request_body}
     ...    server=${CAPIF_HTTPS_URL}
     ...    verify=ca.crt
-    ...    username=${register_user_info_provider['apf_username']}
+    ...    username=${apf_username_to_use}
 
     Check Response Variable Type And Values    ${resp}    201    ServiceAPIDescription
     Dictionary Should Contain Key    ${resp.json()}    apiId
@@ -781,3 +904,14 @@ Create Security Context Between invoker and provider
 
     Check Response Variable Type And Values    ${resp}    201    ServiceSecurity
 
+Get Number Of Services
+    ${resp}=    Get Request Capif
+    ...    /helper/getServices
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${SUPERADMIN_USERNAME}
+
+    Log Dictionary    ${resp.json()}
+    ${size}=    Get Length    ${resp.json()['services']}
+
+    RETURN   ${size}