diff --git a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/auth/api_keys.py b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/auth/api_keys.py
index e70889e3de1..2609de81c5e 100644
--- a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/auth/api_keys.py
+++ b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/auth/api_keys.py
@@ -26,7 +26,7 @@ async def create_api_key(
         product_name=product_name,
         api_key=api_key,
     )
-    assert isinstance(result, ApiKeyGet)
+    assert isinstance(result, ApiKeyGet)  # nosec
     return result
 
 
@@ -45,7 +45,7 @@ async def get_api_key(
         product_name=product_name,
         api_key_id=api_key_id,
     )
-    assert isinstance(result, ApiKeyGet)
+    assert isinstance(result, ApiKeyGet)  # nosec
     return result
 
 
@@ -63,4 +63,4 @@ async def delete_api_key(
         product_name=product_name,
         api_key_id=api_key_id,
     )
-    assert result is None
+    assert result is None  # nosec
diff --git a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/licenses/__init__.py b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/licenses/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/licenses/licensed_items.py b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/licenses/licensed_items.py
new file mode 100644
index 00000000000..e212854bae5
--- /dev/null
+++ b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/licenses/licensed_items.py
@@ -0,0 +1,104 @@
+import logging
+
+from models_library.api_schemas_webserver import WEBSERVER_RPC_NAMESPACE
+from models_library.api_schemas_webserver.licensed_items import (
+    LicensedItemGet,
+    LicensedItemGetPage,
+)
+from models_library.licensed_items import LicensedItemID
+from models_library.products import ProductName
+from models_library.rabbitmq_basic_types import RPCMethodName
+from models_library.resource_tracker import ServiceRunId
+from models_library.users import UserID
+from models_library.wallets import WalletID
+from pydantic import TypeAdapter
+from servicelib.logging_utils import log_decorator
+from servicelib.rabbitmq import RabbitMQRPCClient
+
+_logger = logging.getLogger(__name__)
+
+
+@log_decorator(_logger, level=logging.DEBUG)
+async def get_licensed_items(
+    rabbitmq_rpc_client: RabbitMQRPCClient,
+    *,
+    product_name: str,
+    offset: int,
+    limit: int,
+) -> LicensedItemGetPage:
+    result: LicensedItemGetPage = await rabbitmq_rpc_client.request(
+        WEBSERVER_RPC_NAMESPACE,
+        TypeAdapter(RPCMethodName).validate_python("get_licensed_items"),
+        product_name=product_name,
+        offset=offset,
+        limit=limit,
+    )
+    assert isinstance(result, LicensedItemGetPage)
+    return result
+
+
+@log_decorator(_logger, level=logging.DEBUG)
+async def get_licensed_items_for_wallet(
+    rabbitmq_rpc_client: RabbitMQRPCClient,
+    *,
+    user_id: UserID,
+    product_name: ProductName,
+    wallet_id: WalletID,
+) -> LicensedItemGet:
+    result: LicensedItemGet = await rabbitmq_rpc_client.request(
+        WEBSERVER_RPC_NAMESPACE,
+        TypeAdapter(RPCMethodName).validate_python("get_licensed_items_for_wallet"),
+        user_id=user_id,
+        product_name=product_name,
+        wallet_id=wallet_id,
+    )
+    assert isinstance(result, LicensedItemGet)  # nosec
+    return result
+
+
+@log_decorator(_logger, level=logging.DEBUG)
+async def checkout_licensed_item_for_wallet(
+    rabbitmq_rpc_client: RabbitMQRPCClient,
+    *,
+    user_id: UserID,
+    product_name: ProductName,
+    wallet_id: WalletID,
+    licensed_item_id: LicensedItemID,
+    num_of_seats: int,
+    service_run_id: ServiceRunId,
+) -> None:
+    result = await rabbitmq_rpc_client.request(
+        WEBSERVER_RPC_NAMESPACE,
+        TypeAdapter(RPCMethodName).validate_python("checkout_licensed_item_for_wallet"),
+        user_id=user_id,
+        product_name=product_name,
+        wallet_id=wallet_id,
+        licensed_item_id=licensed_item_id,
+        num_of_seats=num_of_seats,
+        service_run_id=service_run_id,
+    )
+    assert result is None  # nosec
+
+
+@log_decorator(_logger, level=logging.DEBUG)
+async def release_licensed_item_for_wallet(
+    rabbitmq_rpc_client: RabbitMQRPCClient,
+    *,
+    user_id: UserID,
+    product_name: ProductName,
+    wallet_id: WalletID,
+    licensed_item_id: LicensedItemID,
+    num_of_seats: int,
+    service_run_id: ServiceRunId,
+) -> None:
+    result = await rabbitmq_rpc_client.request(
+        WEBSERVER_RPC_NAMESPACE,
+        TypeAdapter(RPCMethodName).validate_python("release_licensed_item_for_wallet"),
+        user_id=user_id,
+        product_name=product_name,
+        wallet_id=wallet_id,
+        licensed_item_id=licensed_item_id,
+        num_of_seats=num_of_seats,
+        service_run_id=service_run_id,
+    )
+    assert result is None  # nosec
diff --git a/services/web/server/src/simcore_service_webserver/licenses/_rpc.py b/services/web/server/src/simcore_service_webserver/licenses/_rpc.py
new file mode 100644
index 00000000000..fede0759b0d
--- /dev/null
+++ b/services/web/server/src/simcore_service_webserver/licenses/_rpc.py
@@ -0,0 +1,80 @@
+from aiohttp import web
+from models_library.api_schemas_webserver import WEBSERVER_RPC_NAMESPACE
+from models_library.api_schemas_webserver.licensed_items import LicensedItemGetPage
+from models_library.basic_types import IDStr
+from models_library.licensed_items import LicensedItemID
+from models_library.products import ProductName
+from models_library.resource_tracker import ServiceRunId
+from models_library.rest_ordering import OrderBy
+from models_library.users import UserID
+from models_library.wallets import WalletID
+from servicelib.rabbitmq import RPCRouter
+
+from ..rabbitmq import get_rabbitmq_rpc_server
+from . import _licensed_items_api
+
+router = RPCRouter()
+
+
+@router.expose()
+async def get_licensed_items(
+    app: web.Application,
+    *,
+    product_name: ProductName,
+    offset: int,
+    limit: int,
+) -> LicensedItemGetPage:
+    licensed_item_get_page: LicensedItemGetPage = (
+        await _licensed_items_api.list_licensed_items(
+            app=app,
+            product_name=product_name,
+            offset=offset,
+            limit=limit,
+            order_by=OrderBy(field=IDStr("name")),
+        )
+    )
+    return licensed_item_get_page
+
+
+@router.expose(reraise_if_error_type=(NotImplementedError,))
+async def get_licensed_items_for_wallet(
+    app: web.Application,
+    *,
+    user_id: UserID,
+    product_name: ProductName,
+    wallet_id: WalletID,
+) -> None:
+    raise NotImplementedError
+
+
+@router.expose(reraise_if_error_type=(NotImplementedError,))
+async def checkout_licensed_item_for_wallet(
+    app: web.Application,
+    *,
+    user_id: UserID,
+    product_name: ProductName,
+    wallet_id: WalletID,
+    licensed_item_id: LicensedItemID,
+    num_of_seats: int,
+    service_run_id: ServiceRunId,
+) -> None:
+    raise NotImplementedError
+
+
+@router.expose(reraise_if_error_type=(NotImplementedError,))
+async def release_licensed_item_for_wallet(
+    app: web.Application,
+    *,
+    user_id: str,
+    product_name: str,
+    wallet_id: WalletID,
+    licensed_item_id: LicensedItemID,
+    num_of_seats: int,
+    service_run_id: ServiceRunId,
+) -> None:
+    raise NotImplementedError
+
+
+async def register_rpc_routes_on_startup(app: web.Application):
+    rpc_server = get_rabbitmq_rpc_server(app)
+    await rpc_server.register_router(router, WEBSERVER_RPC_NAMESPACE, app)
diff --git a/services/web/server/src/simcore_service_webserver/licenses/plugin.py b/services/web/server/src/simcore_service_webserver/licenses/plugin.py
index 6c2ea7ce0d9..137c7b2d1dc 100644
--- a/services/web/server/src/simcore_service_webserver/licenses/plugin.py
+++ b/services/web/server/src/simcore_service_webserver/licenses/plugin.py
@@ -7,7 +7,8 @@
 from servicelib.aiohttp.application_keys import APP_SETTINGS_KEY
 from servicelib.aiohttp.application_setup import ModuleCategory, app_module_setup
 
-from . import _licensed_items_handlers, _licensed_items_purchases_handlers
+from ..rabbitmq import setup_rabbitmq
+from . import _licensed_items_handlers, _licensed_items_purchases_handlers, _rpc
 
 _logger = logging.getLogger(__name__)
 
@@ -25,3 +26,7 @@ def setup_licenses(app: web.Application):
     # routes
     app.router.add_routes(_licensed_items_handlers.routes)
     app.router.add_routes(_licensed_items_purchases_handlers.routes)
+
+    setup_rabbitmq(app)
+    if app[APP_SETTINGS_KEY].WEBSERVER_RABBITMQ:
+        app.on_startup.append(_rpc.register_rpc_routes_on_startup)
diff --git a/services/web/server/tests/unit/with_dbs/04/licenses/test_licenses_rpc.py b/services/web/server/tests/unit/with_dbs/04/licenses/test_licenses_rpc.py
new file mode 100644
index 00000000000..e3ab4f4cb3d
--- /dev/null
+++ b/services/web/server/tests/unit/with_dbs/04/licenses/test_licenses_rpc.py
@@ -0,0 +1,127 @@
+# pylint: disable=redefined-outer-name
+# pylint: disable=unused-argument
+# pylint: disable=unused-variable
+
+
+from collections.abc import Awaitable, Callable
+
+import pytest
+from aiohttp.test_utils import TestClient
+from models_library.licensed_items import LicensedResourceType
+from models_library.products import ProductName
+from pytest_mock import MockerFixture
+from pytest_simcore.helpers.monkeypatch_envs import setenvs_from_dict
+from pytest_simcore.helpers.typing_env import EnvVarsDict
+from pytest_simcore.helpers.webserver_login import UserInfoDict
+from servicelib.rabbitmq import RabbitMQRPCClient
+from servicelib.rabbitmq.rpc_interfaces.webserver.licenses.licensed_items import (
+    checkout_licensed_item_for_wallet,
+    get_licensed_items,
+    get_licensed_items_for_wallet,
+    release_licensed_item_for_wallet,
+)
+from settings_library.rabbit import RabbitSettings
+from simcore_postgres_database.models.users import UserRole
+from simcore_service_webserver.application_settings import ApplicationSettings
+from simcore_service_webserver.licenses import _licensed_items_db
+
+pytest_simcore_core_services_selection = [
+    "rabbit",
+]
+
+
+@pytest.fixture
+def app_environment(
+    rabbit_service: RabbitSettings,
+    app_environment: EnvVarsDict,
+    monkeypatch: pytest.MonkeyPatch,
+):
+    new_envs = setenvs_from_dict(
+        monkeypatch,
+        {
+            **app_environment,
+            "RABBIT_HOST": rabbit_service.RABBIT_HOST,
+            "RABBIT_PORT": f"{rabbit_service.RABBIT_PORT}",
+            "RABBIT_USER": rabbit_service.RABBIT_USER,
+            "RABBIT_SECURE": f"{rabbit_service.RABBIT_SECURE}",
+            "RABBIT_PASSWORD": rabbit_service.RABBIT_PASSWORD.get_secret_value(),
+        },
+    )
+
+    settings = ApplicationSettings.create_from_envs()
+    assert settings.WEBSERVER_RABBITMQ
+
+    return new_envs
+
+
+@pytest.fixture
+def user_role() -> UserRole:
+    return UserRole.USER
+
+
+@pytest.fixture
+async def rpc_client(
+    rabbitmq_rpc_client: Callable[[str], Awaitable[RabbitMQRPCClient]],
+    mocker: MockerFixture,
+) -> RabbitMQRPCClient:
+    return await rabbitmq_rpc_client("client")
+
+
+async def test_api_keys_workflow(
+    client: TestClient,
+    rpc_client: RabbitMQRPCClient,
+    osparc_product_name: ProductName,
+    logged_user: UserInfoDict,
+    pricing_plan_id: int,
+):
+    assert client.app
+
+    result = await get_licensed_items(
+        rpc_client, product_name=osparc_product_name, offset=0, limit=20
+    )
+    assert len(result.items) == 0
+    assert result.total == 0
+
+    await _licensed_items_db.create(
+        client.app,
+        product_name=osparc_product_name,
+        name="Model A",
+        licensed_resource_type=LicensedResourceType.VIP_MODEL,
+        pricing_plan_id=pricing_plan_id,
+    )
+
+    result = await get_licensed_items(
+        rpc_client, product_name=osparc_product_name, offset=0, limit=20
+    )
+    assert len(result.items) == 1
+    assert result.total == 1
+
+    with pytest.raises(NotImplementedError):
+        await get_licensed_items_for_wallet(
+            rpc_client,
+            user_id=logged_user["id"],
+            product_name=osparc_product_name,
+            wallet_id=1,
+        )
+
+    with pytest.raises(NotImplementedError):
+        await checkout_licensed_item_for_wallet(
+            rpc_client,
+            user_id=logged_user["id"],
+            product_name=osparc_product_name,
+            wallet_id=1,
+            licensed_item_id="c5139a2e-4e1f-4ebe-9bfd-d17f195111ee",
+            num_of_seats=1,
+            service_run_id="run_1",
+        )
+
+    with pytest.raises(NotImplementedError):
+        await release_licensed_item_for_wallet(
+            rpc_client,
+            user_id=logged_user["id"],
+            product_name=osparc_product_name,
+            wallet_id=1,
+            licensed_item_id="c5139a2e-4e1f-4ebe-9bfd-d17f195111ee",
+            num_of_seats=1,
+            service_run_id="run_1",
+        )