A support agent logs into your seller portal. They type a URL:
myapp.com/earnings
And the entire Earnings micro frontend loads. Payouts, transactions, the lot — for a user who should only ever see the Support module.
Here's why it happens. In a federated host, every remote is mounted by a route:
<Route path="earnings/*" element={<EarningsMFE />} />
<Route path="orders/*" element={<OrdersMFE />} />
<Route path="reports/*" element={<ReportsMFE />} />
That <Route> renders for anyone who reaches it. It has no idea what the current user is allowed to see — it just renders. The nav bar makes it worse by showing all ten menu items to everyone.
In a single SPA this is easy to forget. In a micro frontend, each remote is a separately deployed bundle and the host mounts it by path — so authorization has to become a first-class concern of the routing layer.
The full guide covers the complete pattern:
-
Flattening the backend's nested permissions tree into a flat array of keys (
orders_view,orders_returns_approve) — once, at the auth boundary - Storing permissions in the shared Redux auth slice as a Module Federation singleton
- A
usePermissionshook withcan/hasAny/hasAlland O(1) Set lookups - A
<PermissionRoute>guard that redirects before Suspense resolves — so the blocked remote's bundle is never downloaded - Driving the menu and the guards from one config so they never drift
- Why route guards, menu filters, and component gates are all UX — and the backend 403 is the only real boundary
Read the full guide with all the code examples → https://blog.srinudesetti.in/micro-frontend/state-management/permission-based-routing-micro-frontend
Top comments (0)