Article Guide
Senior14 min readJune 13, 2026

Authentication and Authorization in Micro Frontends

Learn how to design authentication and authorization in micro frontend architecture, including shell-owned auth bootstrap, token handling, session refresh, remote identity context, permission checks, logout, security risks, and interview tradeoffs.

Tags:
Micro FrontendsAuthenticationAuthorizationFrontend ArchitectureSecurityInterview Prep

Authentication and authorization become more complex when a frontend is split into multiple independently owned micro apps.

In a monolithic frontend, auth is usually simple:

textEditor
One app
One router
One session provider
One auth guard
One token handling flow

In a micro frontend system, you may have:

textEditor
Shell App
Catalog Remote
Cart Remote
Checkout Remote
Profile Remote
Orders Remote
Admin Remote

Now the questions become:

textEditor
Who checks whether the user is logged in?
Who refreshes the token?
How do remotes know the current user?
Can remotes access tokens?
Who handles logout?
Where should permission checks happen?
What happens when the session expires?

This article explains how to design authentication and authorization in micro frontends in a clean, secure, and interview-ready way.

1. Authentication vs Authorization

Before designing the system, separate these two concepts.

Authentication

Authentication answers:

textEditor
Who is the user?

Examples:

  • Login
  • Logout
  • Session validation
  • Token refresh
  • Identity bootstrap

Authorization

Authorization answers:

textEditor
What is the user allowed to do?

Examples:

  • Can the user view orders?
  • Can the user edit profile?
  • Can the user access admin tools?
  • Can the user place an order?
  • Can the user use a payment method?

Simple rule:

Authentication = identity Authorization = permission

In micro frontends, the shell often handles authentication bootstrap, while remotes handle feature-level authorization.

2. Core Auth Principle

The recommended principle is:

The shell should own authentication bootstrap, but remotes and backend APIs must still enforce authorization.

The shell can answer:

  • Is the user logged in?
  • What is the session status?
  • Should this protected route load?
  • Should we redirect to login?

The remote can answer:

  • Can this user use this feature?
  • Should this button be visible?
  • Can this user edit this resource?

The backend must answer:

  • Is this request actually allowed?

Frontend checks improve UX.

Backend checks protect the system.

3. High-Level Auth Architecture

A common architecture:

architecture diagram
                    ┌──────────────────────┐
                    │       Browser         │
                    └──────────┬───────────┘
                               │
                               ▼
                    ┌──────────────────────┐
                    │      Shell App        │
                    │ Auth Bootstrap        │
                    │ Session Provider      │
                    │ Route Guard           │
                    └──────────┬───────────┘
                               │
          ┌────────────────────┼────────────────────┐
          │                    │                    │
          ▼                    ▼                    ▼
┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│ Profile Remote  │  │ Orders Remote   │  │ Checkout Remote │
│ Feature AuthZ   │  │ Feature AuthZ   │  │ Feature AuthZ   │
└────────┬────────┘  └────────┬────────┘  └────────┬────────┘
         │                    │                    │
         ▼                    ▼                    ▼
┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│ Profile API     │  │ Orders API      │  │ Checkout API    │
│ Backend AuthZ   │  │ Backend AuthZ   │  │ Backend AuthZ   │
└─────────────────┘  └─────────────────┘  └─────────────────┘

The shell gives a consistent authentication experience.

The remotes apply domain-specific permission logic.

The backend enforces real security.

4. Shell Responsibilities

The shell usually owns platform-level authentication concerns.

Shell responsibilities:

textEditor
Login detection
Session bootstrap
Token refresh orchestration
Logout handling
Global route protection
Identity context provider
Auth loading state
Redirect to login
Redirect after login
Session expiry handling

Example shell flow:

flow diagram
User opens /orders
      │
      ▼
Shell checks session
      │
      ├── Not logged in → redirect to /login?redirect=/orders
      │
      └── Logged in → load Orders Remote

This keeps the global authentication experience consistent.

5. Remote Responsibilities

Remotes should not usually own the global login flow.

They should own domain-specific authorization and UX behavior.

Remote responsibilities:

textEditor
Feature-level permission checks
Role-based UI visibility
Domain route restrictions
Calling domain APIs
Handling 401/403 responses gracefully
Displaying permission-specific empty states

Example: Orders Remote

  • Orders Remote checks if user can view order history
  • Calls Orders API
  • Handles 403 forbidden response
  • Shows “You do not have access to this order” if needed

Example: Checkout Remote

  • Checkout Remote checks if user can place order
  • Checks delivery/payment eligibility
  • Calls Checkout API
  • Handles payment/session authorization errors

The remote owns the domain experience.

6. Backend Responsibilities

Backend APIs must enforce real authorization.

Never rely only on frontend checks.

Backend responsibilities:

  • Validate access token/session
  • Validate user permissions
  • Validate resource ownership
  • Reject unauthorized requests
  • Reject forbidden actions
  • Apply business rules
  • Audit sensitive actions

Example:

textEditor
User manually calls:
GET /orders/order_123

Even if the frontend hides the order page, the backend must still verify:

  • Does this user own order_123?
  • Is the user allowed to view it?

Strong interview phrase:

Frontend authorization improves user experience, but backend authorization protects the system.

7. Identity Context

The shell can provide a safe identity context to remotes.

Example identity context:

jsonEditor
{
  "isAuthenticated": true,
  "userId": "user_123",
  "displayName": "Avick",
  "roles": ["customer"],
  "locale": "en-IN",
  "currency": "INR"
}

This is useful for rendering UI.

But be careful.

Do not expose sensitive data unnecessarily.

Avoid passing:

  • Raw access tokens through props
  • Refresh tokens
  • Secrets
  • Payment data
  • Sensitive profile data
  • Full permission graph if not needed

Give remotes only what they need.

8. Token Handling

Token handling must be designed carefully.

Common options:

  • HTTP-only secure cookies
  • In-memory token storage
  • Auth SDK managed session
  • Backend session
  • Token passed through API layer

Avoid storing sensitive tokens in:

  • localStorage
  • sessionStorage
  • Custom browser events
  • Global window variables
  • URL query params

Bad:

/cart?token=eyJhbGciOi...

Bad:

window.__ACCESS_TOKEN__ = token

Better:

  • Use HTTP-only secure cookies where possible.
  • Let API calls include credentials safely.
  • Keep token access centralized.

Exact implementation depends on your auth provider and backend architecture, but the principle is stable:

Do not spread token handling across every remote.

9. Should Remotes Access Tokens?

Ideally, remotes should not directly manage tokens.

Better options:

  • Shell/auth provider initializes session.
  • API client attaches credentials.
  • Backend validates session/token.
  • Remotes call domain APIs through approved clients.

If remotes directly handle tokens, you risk:

  • Inconsistent refresh logic
  • Security leaks
  • Different token storage strategies
  • Hard logout coordination
  • Duplicate auth code
  • Inconsistent error handling

A platform-owned auth layer keeps behavior consistent.

10. Session Bootstrap Flow

When the app starts, the shell can bootstrap session state.

flow diagram
Browser loads Shell
      │
      ▼
Shell initializes auth provider
      │
      ▼
Shell checks existing session
      │
      ├── Loading → show app skeleton
      ├── Unauthenticated → public routes only
      └── Authenticated → identity context ready

Then routes can load remotes.

Example:

flow diagram
Authenticated user opens /profile
      │
      ▼
Shell confirms session
      │
      ▼
Shell loads Profile Remote
      │
      ▼
Profile Remote fetches profile data

Do not load protected remotes before the auth state is known unless the route supports it safely.

11. Token Refresh Flow

Token/session refresh should be centralized.

Bad approach:

  • Catalog Remote refreshes token.
  • Cart Remote refreshes token.
  • Checkout Remote refreshes token.
  • Profile Remote refreshes token.

This can cause race conditions and inconsistent behavior.

Better:

  • Shell/auth provider handles refresh.
  • Remotes use API layer.
  • 401 handling is standardized.

Flow:

flow diagram
API request receives 401
      │
      ▼
Auth layer attempts refresh
      │
      ├── Refresh succeeds → retry request
      └── Refresh fails → logout or redirect to login

This keeps auth behavior consistent.

12. Logout Flow

Logout must clear the full application session.

A good logout flow:

flow diagram
User clicks logout
      │
      ▼
Shell calls auth logout
      │
      ▼
Session/cookies cleared
      │
      ▼
In-memory identity context cleared
      │
      ▼
Remotes are notified through safe event/context update
      │
      ▼
User redirected to login or public home

Remotes should respond to logout by clearing sensitive local UI state.

Example:

  • Cart Remote clears in-memory cart summary.
  • Profile Remote clears profile cache.
  • Orders Remote clears order list cache.

Do not rely on remotes to perform the primary logout.

The shell/auth layer should own it.

13. Protected Routes

Some routes require authentication.

Examples:

  • /profile
  • /orders
  • /checkout

Shell-level protected route flow:

flow diagram
User opens /orders
      │
      ▼
Shell checks auth state
      │
      ├── unauthenticated → /login?redirect=/orders
      └── authenticated → load Orders Remote

Remote-level feature guard:

flow diagram
Orders Remote loads
      │
      ▼
Checks permission/resource access
      │
      ├── allowed → render orders
      └── forbidden → show no-access state

Both levels are useful.

14. Public Routes

Not all routes need authentication.

Examples:

  • /
  • /categories/:slug
  • /search
  • /product/:id
  • /campaign/:slug

Public remotes should still be careful.

They may have mixed behavior:

  • Anonymous user can view product.
  • Logged-in user can see personalized price or wishlist.

The shell can provide optional identity context.

Remote should handle both states.

Example:

  • Product Remote ├── Anonymous: show product └── Logged in: show wishlist and personalized offers

15. Authorization Models

Common frontend authorization models:

  • Role-based access control
  • Permission-based access control
  • Feature-flag-based access
  • Resource ownership checks
  • Plan/subscription-based access

Examples:

  • Admin can access admin remote.
  • Customer can view own orders.
  • Premium user can access premium feature.
  • Store manager can edit catalog.

Frontend can hide or show UI based on these rules, but backend must enforce them.

16. Role-Based UI

Role-based UI can live inside remotes.

Example:

  • Customer sees profile details
  • Support agent sees customer assistance panel
  • Admin sees account control tools

The shell should not know every domain-specific permission.

Bad:

Shell decides whether profile edit button appears.

Good:

Profile Remote decides profile feature visibility using identity/permissions.

The shell may provide the identity summary, but the remote owns the domain UI.

17. Permission Context

Instead of passing raw roles everywhere, some systems expose a permission context.

Example:

jsonEditor
{
  "permissions": [
    "orders:view",
    "profile:edit",
    "checkout:place_order"
  ]
}

A remote can check:

  • Can user perform profile:edit?
  • Can user perform orders:view?
  • Can user perform checkout:place_order?

Benefits:

  • More precise than roles
  • Easier feature checks
  • Clearer domain permissions

Risk:

  • Too much permission logic duplicated in frontend
  • Large permission object exposed unnecessarily

Keep it minimal and safe.

18. Handling 401 and 403

Remotes must handle API auth failures gracefully.

401 Unauthorized

Means:

User is not authenticated or session expired.

Possible behavior:

  • Trigger refresh
  • Redirect to login
  • Show session expired message

403 Forbidden

Means:

User is authenticated but not allowed.

Possible behavior:

  • Show no-access page
  • Hide restricted action
  • Show permission error

Do not treat 401 and 403 the same.

Example:

  • 401 → login required
  • 403 → access denied

19. Auth and Routing

Auth is closely tied to routing.

Example protected flow:

flow diagram
User opens /checkout
      │
      ▼
Shell checks auth
      │
      ├── not logged in → /login?redirect=/checkout
      └── logged in → load Checkout Remote

After login:

flow diagram
Login success
      │
      ▼
Redirect back to /checkout

This preserves user intent.

Bad UX:

User tries checkout. Login succeeds. User lands on homepage. Cart journey is lost.

Good UX:

Return user to original route after successful login.

Redirect logic should be consistent across remotes.

The shell is usually the right place for global redirect rules.

20. Auth and Deep Linking

Deep links must work with auth.

Example:

textEditor
/orders/order_123

Flow:

flow diagram
User opens deep link
      │
      ▼
Shell checks auth
      │
      ├── not logged in → login with redirect
      └── logged in → load Orders Remote
                              │
                              ▼
                      Orders Remote checks order access

If user does not own the order:

Show 403/no access

If order does not exist:

Show 404/not found

Auth, routing, and domain validation must work together.

21. Cross-App Auth Events

Some global auth events are useful.

Examples:

  • auth:logged-in
  • auth:logged-out
  • auth:session-expired
  • auth:token-refreshed

Use carefully.

Good event:

auth:logged-out Payload: { reason: "user_action" }

Bad event:

auth:token-refreshed Payload: { accessToken: "..." }

Never pass raw tokens through browser events.

22. Auth State and Browser Storage

Be careful with browser storage.

Avoid:

  • localStorage for access tokens
  • sessionStorage for refresh tokens
  • localStorage as cross-remote auth API

Safer options often include:

  • HTTP-only secure cookies
  • Backend-managed session
  • Auth SDK-managed secure flow
  • In-memory short-lived token access

The exact choice depends on architecture, but never spread storage decisions across remotes.

23. Security Risks

Common security risks in micro frontend auth:

RiskWhy It Is Dangerous
Tokens in localStorageXSS exposure
Tokens in URLLeaks through logs/history
Tokens in browser eventsAny listener may read them
Remote owns refresh logicInconsistent and risky
Shell trusts frontend-only permissionsBackend bypass possible
Sensitive identity passed to all remotesData exposure
Untrusted remote loadedExecutable JS risk
Logout does not clear remote cacheSensitive data may remain
Different auth handling per remoteInconsistent security

Security must be centralized where possible and enforced at the backend.

24. Auth in E-commerce Example

Route access:

RouteAuth Required?Owner
/NoHome Remote
/categories/:slugNoCatalog Remote
/product/:idNoProduct Remote
/cartOptional/dependsCart Remote
/checkoutUsually yesCheckout Remote
/profileYesProfile Remote
/ordersYesOrders Remote
/adminYes + roleAdmin Remote

Example checkout flow:

flow diagram
User opens /checkout
      │
      ▼
Shell checks login
      │
      ├── anonymous → /login?redirect=/checkout
      └── authenticated → load Checkout Remote

Checkout Remote then checks:

  • Can user place order?
  • Is cart valid?
  • Is delivery address allowed?
  • Is payment method valid?

Backend finally enforces all rules.

25. Multi-Tenant / Role-Based Systems

In enterprise apps, auth may include tenant or organization context.

Example:

jsonEditor
{
  "userId": "user_123",
  "tenantId": "tenant_456",
  "roles": ["admin"],
  "permissions": ["users:view", "billing:edit"]
}

Micro frontend implications:

  • Shell bootstraps tenant context.
  • Remote checks domain permissions.
  • APIs validate tenant access.
  • Route changes preserve tenant scope.

Example routes:

  • /org/acme/users
  • /org/acme/billing
  • /org/acme/audit-logs

Tenant context must be consistent across remotes.

26. Testing Auth in Micro Frontends

Test auth at multiple levels.

Test cases:

  • Unauthenticated user opens protected route.
  • User logs in and returns to original route.
  • Session expires while remote is open.
  • Remote receives 403 from API.
  • Logout clears shell and remote state.
  • Deep link to protected nested route works.
  • Role-based UI appears correctly.
  • Unauthorized user cannot access admin remote.

Important E2E journeys:

  • Login → profile
  • Login → checkout
  • Session expiry → redirect
  • Logout → protected route blocked
  • Admin user → admin page allowed
  • Normal user → admin page denied

Auth bugs can create both security and UX problems.

27. Observability for Auth

Track auth-related events:

  • Login success/failure
  • Logout
  • Session refresh success/failure
  • Protected route redirects
  • 401 responses
  • 403 responses
  • Session expiry
  • Auth provider errors
  • Remote permission failures

Useful fields:

textEditor
route
remoteName
shellVersion
remoteVersion
authState
errorType
permission
userRoleGroup

Do not log sensitive tokens or private user data.

28. Common Anti-Patterns

Anti-PatternWhy It Is Bad
Each remote implements its own loginInconsistent UX/security
Tokens passed through props/eventsSecurity risk
Tokens stored in localStorageXSS exposure
Shell owns all permission logicShell becomes domain-aware
Remotes trust frontend-only permissionsBackend bypass risk
No session refresh strategyRandom auth failures
No logout coordinationSensitive stale data
Same handling for 401 and 403Wrong UX
No redirect preservationBroken user journeys
Auth logic duplicated everywhereMaintenance and security risk

29. Interview Questions

Q1. Where should authentication live in micro frontends?

Authentication bootstrap should usually live in the shell or platform layer. The shell can initialize the session, handle login/logout, refresh tokens, and protect top-level routes. Remotes consume safe identity context and handle domain-specific authorization.

Q2. Where should authorization live?

Authorization should exist at multiple levels. The shell can handle broad route protection, remotes can handle feature-level permissions, and backend APIs must enforce real authorization. Frontend checks are not enough for security.

Q3. Should remotes access tokens directly?

Ideally no. Token handling should be centralized through the shell/auth provider or approved API layer. Passing tokens to every remote increases security risk and creates inconsistent refresh/logout behavior.

Q4. How do you handle session expiry?

The shared auth layer should detect session expiry or refresh failure, clear identity context, notify the app safely, and redirect the user to login while preserving the original route where appropriate.

Q5. How do you handle logout across remotes?

The shell/auth layer should own logout. After logout, it clears the session and identity context, notifies remotes safely, and redirects the user. Remotes should clear sensitive in-memory data when auth state changes.

Q6. What is the biggest security mistake in micro frontend auth?

One major mistake is spreading token handling across remotes or exposing tokens through localStorage, browser events, URL params, or global variables. Another is relying only on frontend permission checks without backend enforcement.

30. Strong Senior Answer

If an interviewer asks:

“How would you design authentication and authorization in micro frontends?”

A strong answer:

I would keep authentication bootstrap in the shell or platform layer. The shell would initialize the auth provider, check the session, handle token refresh, protect top-level routes, manage logout, and preserve redirect URLs after login. Remotes would not implement their own login flows. They would consume a safe identity context from the shell, such as user ID, logged-in status, locale, and minimal role or permission information. Each remote would handle feature-level authorization inside its domain. For example, Orders Remote decides whether the user can view order history, and Checkout Remote decides whether the user can access specific checkout actions. Backend APIs must still enforce authorization because frontend checks are only for user experience, not real security. I would avoid passing raw tokens through props, browser events, localStorage, or URLs. Token/session handling should be centralized through the platform auth layer or secure API client. The key principle is: shell owns authentication bootstrap, remotes own domain authorization UX, and backend APIs enforce security.

31. Final Auth Checklist

  • Does the shell own authentication bootstrap?
  • Is login/logout centralized?
  • Is token/session refresh centralized?
  • Are protected routes guarded?
  • Is redirect-after-login preserved?
  • Do remotes avoid implementing separate login flows?
  • Is identity context minimal and safe?
  • Are raw tokens kept out of browser events and URLs?
  • Are tokens avoided in localStorage where possible?
  • Do remotes handle feature-level authorization?
  • Do backend APIs enforce real authorization?
  • Are 401 and 403 handled differently?
  • Does logout clear sensitive remote state?
  • Are auth failures observable?
  • Are deep links to protected routes supported?

32. Summary

Authentication and authorization in micro frontends require clear ownership.

Recommended model:

textEditor
Shell owns authentication bootstrap.
Shell owns top-level route protection.
Remotes own feature-level authorization UX.
Backend APIs enforce real authorization.
Token handling is centralized.
Identity context is minimal and safe.
Logout is coordinated globally.

Avoid:

textEditor
Each remote having its own login flow.
Passing tokens through events or URLs.
Storing sensitive tokens casually in browser storage.
Putting all permission logic in the shell.
Trusting frontend-only authorization.

The strongest takeaway:

In micro frontends, authentication should be centralized for consistency, authorization should be domain-aware, and real security must be enforced by the backend.

References

  • Micro Frontends — Martin Fowler (https://martinfowler.com/articles/micro-frontends.html)
  • Micro Frontends (https://micro-frontends.org)
  • webpack Module Federation Documentation (https://webpack.js.org/concepts/module-federation/)
  • AWS Prescriptive Guidance: Micro-frontends (https://docs.aws.amazon.com/prescriptive-guidance/latest/micro-frontends-aws/introduction.html)
  • Module Federation Official Site (https://module-federation.io)