Summary
Plugins can register custom REST routes with GatewayPlugin::get_routes(). These routes are served by the same HTTP server and pass through the auth pre-routing handler. But a plugin route cannot be tied to an RBAC role.
The role permission map in AuthConfig::get_role_permissions() is a fixed allowlist of core route paths (METHOD:/path patterns). AuthManager::check_authorization() denies any path that matches no pattern for the caller's role, and no role has a catch-all pattern. A plugin route path is in no role's set. The result:
- With auth enabled, a plugin route that needs a token (for example any write method when
require_auth_for: write) is denied for every role, including admin. The route returns 403 for everyone, so it cannot be used.
- With auth disabled, the same route is open to anyone.
There is no option in between. A plugin author cannot say "this route needs the operator role" and have the gateway enforce it the way it does for core routes. This blocks any plugin that needs a write endpoint restricted to a specific role.
Proposed solution
Let a plugin route declare a required role, and make the auth path honor it. For example, add an optional role field to PluginRoute, and have the role check (AuthManager::check_authorization(), or the route registration step) consult the plugin routes so the plugin pattern is matched against the declared role. Then a plugin route is gated by the same RBAC as core routes, with no extra secret and without the plugin reading or verifying the JWT itself.
Two alternatives that do not work well:
- The plugin verifies the JWT itself. It needs the signing key or JWK, which the plugin does not have.
- A separate shared secret on the plugin route. This bypasses the RBAC model and adds a second auth system to maintain.
Additional context
Relevant code:
src/ros2_medkit_gateway/include/ros2_medkit_gateway/core/plugins/gateway_plugin.hpp - the PluginRoute struct.
src/ros2_medkit_gateway/src/core/auth/auth_config.cpp - get_role_permissions().
src/ros2_medkit_gateway/src/core/auth/auth_manager.cpp - check_authorization(), which denies by default when no pattern matches.
src/ros2_medkit_gateway/src/http/rest_server.cpp - plugin routes registered under the same pre-routing auth handler as core routes.
Summary
Plugins can register custom REST routes with
GatewayPlugin::get_routes(). These routes are served by the same HTTP server and pass through the auth pre-routing handler. But a plugin route cannot be tied to an RBAC role.The role permission map in
AuthConfig::get_role_permissions()is a fixed allowlist of core route paths (METHOD:/pathpatterns).AuthManager::check_authorization()denies any path that matches no pattern for the caller's role, and no role has a catch-all pattern. A plugin route path is in no role's set. The result:require_auth_for: write) is denied for every role, including admin. The route returns 403 for everyone, so it cannot be used.There is no option in between. A plugin author cannot say "this route needs the operator role" and have the gateway enforce it the way it does for core routes. This blocks any plugin that needs a write endpoint restricted to a specific role.
Proposed solution
Let a plugin route declare a required role, and make the auth path honor it. For example, add an optional role field to
PluginRoute, and have the role check (AuthManager::check_authorization(), or the route registration step) consult the plugin routes so the plugin pattern is matched against the declared role. Then a plugin route is gated by the same RBAC as core routes, with no extra secret and without the plugin reading or verifying the JWT itself.Two alternatives that do not work well:
Additional context
Relevant code:
src/ros2_medkit_gateway/include/ros2_medkit_gateway/core/plugins/gateway_plugin.hpp- thePluginRoutestruct.src/ros2_medkit_gateway/src/core/auth/auth_config.cpp-get_role_permissions().src/ros2_medkit_gateway/src/core/auth/auth_manager.cpp-check_authorization(), which denies by default when no pattern matches.src/ros2_medkit_gateway/src/http/rest_server.cpp- plugin routes registered under the same pre-routing auth handler as core routes.