
Identity Architecture Patterns for Micro-Frontends and Multi-Platform
An examination of identity architecture patterns for micro-frontends and multi-platform environments, covering BFF, cross-platform SSO, and unified identity strategies.
The fundamental challenge in modern distributed architectures is not merely routing requests, but maintaining a consistent security boundary when the user interface is fragmented. In a monolithic application, the browser trusts the server because the server renders the HTML. When you decompose this into micro-frontends or deploy to native mobile, IoT, and web simultaneously, you lose that singular boundary. Each client becomes a potential attack surface, and the mechanism of "trust" must move from the browser to a dedicated mediation layer. Without this shift, credentials leak, session hijacking becomes trivial, and audit trails fracture.
The Fragmentation of Trust
Consider a scenario where a frontend team splits a dashboard into three micro-frontend modules: billing, analytics, and profile. These modules are deployed from different repositories, potentially even different CDNs. In a traditional setup, a single sessionid cookie might track the user. However, in a micro-frontend environment, if billing is served from billing.example.com and analytics from analytics.example.com, the browser cannot share a cookie set by one domain with the other due to Same-Origin Policy.
This fragmentation forces the application to manage state manually. If a user logs in on the billing micro-frontend, the analytics module has no knowledge of that session unless an external signal is passed. The naive solution is to pass tokens in URL parameters or LocalStorage across all domains. This is a critical failure point. LocalStorage is accessible to any script running on the page, making it vulnerable to Cross-Site Scripting (XSS). If an attacker injects a script into the profile module, they can exfiltrate the token stored in analytics.
The mechanism required here is the separation of concerns between the client's ability to render and its ability to authenticate. The client should never hold the "master key." Instead, it should hold a "visitor pass" that is validated by a gatekeeper. This is where the Backend-for-Frontend (BFF) pattern becomes the architectural linchpin.
The Backend-for-Frontend (BFF) Pattern
The BFF pattern solves the fragmentation problem by introducing a lightweight server layer tailored to each client type. For a web micro-frontend, you deploy a BFF; for a mobile app, you deploy a mobile-specific BFF; for a native desktop app, another.
Let's trace the mechanism of a login flow using the BFF. When a user attempts to log in on the web micro-frontend, the request does not go directly to the Identity Provider (IdP). Instead, it goes to the Web BFF.
GET https://web-bff.example.com/auth/login?redirect=https://billing.example.com/dashboardThe Web BFF initiates an OAuth 2.0 / OpenID Connect (OIDC) Authorization Code Flow as defined in RFC 6749. It generates a unique state parameter to prevent CSRF and redirects the user's browser to the IdP. The IdP authenticates the user and redirects back to the Web BFF with an authorization code.
Here is the critical distinction: the Web BFF exchanges this code for tokens at the IdP's token endpoint.
POST https://auth.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
code=SplxlOBeZQQYbYS6WxSbIA
redirect_uri=https://web-bff.example.com/callback
client_id=my-client
client_secret=super-secret-keyThe IdP responds with an access_token and a refresh_token. The Web BFF stores these tokens in its own server-side session (e.g., Redis or a database). It then issues a short-lived, HTTP-only, Secure cookie to the browser containing a session identifier. The browser now only holds a reference to the server's session, not the actual credentials.
This mechanism ensures that even if an XSS attack compromises the billing micro-frontend, the attacker cannot extract the refresh_token because it resides on the BFF, not in the browser's LocalStorage. The attacker can only make requests with the short-lived access_token (which the BFF can revoke immediately), drastically reducing the window of opportunity for an attack.
For mobile or IoT devices where cookies are problematic, the BFF acts as a proxy. The mobile app sends a request to the BFF. The BFF checks its internal session, fetches a fresh access token from the IdP if necessary, and forwards the request to the downstream API Gateway. The mobile app never sees the IdP's secrets.
Cross-Platform SSO via OIDC
When users switch between the web micro-frontend and the mobile app, they expect to be logged in automatically (Single Sign-On). Achieving this without sharing cookies is possible through the OIDC standard, specifically the Authorization Code Flow with PKCE (Proof Key for Code Exchange) RFC 7636.
The mechanism relies on the IdP being the central authority. When a user logs in on the web BFF, the IdP creates a session and sets a session cookie. When the user switches to the mobile app, the app initiates a login flow.
- The mobile app generates a
code_verifierand derives acode_challenge. - The app redirects the user (via a deep link or system browser) to the IdP.
- The IdP detects the existing session cookie (if the user is already authenticated in the system browser) and skips the login screen.
- The IdP returns an authorization code to the mobile app.
- The mobile app sends the authorization code to the Mobile BFF. The Mobile BFF exchanges the code for tokens, stores the refresh token, and returns a short-lived session token to the mobile app.
Crucially, the mobile app does not store these tokens indefinitely. It passes them to the Mobile BFF. The Mobile BFF then validates these tokens against the IdP.
If the architecture uses a unified identity strategy, the IdP issues a JWT (JSON Web Token) containing the user's unique identifier (sub) and roles. The Mobile BFF and Web BFF both trust this JWT.
{
"iss": "https://auth.example.com",
"sub": "user-12345",
"aud": "mobile-app",
"roles": ["admin", "viewer"],
"iat": 1678886400,
"exp": 1678890000
}The mechanism here is "stateless validation." The downstream microservices do not need to query a database to check if the user is logged in. They verify the JWT signature using the IdP's public key. If the signature is valid and the token is not expired, the user is authenticated. This allows the Web BFF and Mobile BFF to maintain separate sessions while presenting a unified identity to the backend services. Bearer tokens used in this context are governed by RFC 6750.
Unified Identity State Management
The final piece of the puzzle is ensuring that the identity propagated to the backend is consistent. In a micro-frontend setup, the API Gateway sits in front of all microservices. It receives requests from the Web BFF, Mobile BFF, and potentially direct native clients.
The API Gateway must be configured to validate the Authorization: Bearer <token> header. It extracts the sub (subject) claim from the JWT. This sub is the unique identifier that unifies the user across all platforms.
When the Web BFF proxies a request to the billing-service, it includes the access_token obtained from the IdP. The billing-service validates the token. If the token is valid, the service knows it is operating on behalf of user-12345.
However, a subtle risk exists: token expiration. If the access_token expires while the user is active, the Web BFF must silently refresh it. The mechanism involves the Web BFF holding the refresh_token and calling the IdP's token endpoint in the background to get a new access_token before forwarding the user's request.
This architecture creates a clear data flow:
- Client: Holds no secrets. Only holds a session reference or a short-lived token.
- BFF: Holds the long-lived
refresh_token. Acts as the bridge. - IdP: The source of truth. Issues tokens and manages sessions.
- API Gateway: Validates tokens and routes traffic.
- Microservices: Trust the token and act on the
sub.
This separation ensures that if a micro-frontend is compromised, the attacker gains no leverage against the IdP or the BFF's secrets. If the BFF is compromised, the attacker still needs to bypass the IdP's token validation logic.
Common Pitfalls
Implementing the BFF pattern introduces specific failure modes that must be anticipated.
- Clock Skew in JWT Validation: JWTs rely on
iat(issued at) andexp(expiration) timestamps. If the clock on the BFF, API Gateway, or IdP drifts even slightly, valid tokens may be rejected or invalid tokens accepted. RFC 7519 recommends allowing a small leeway (e.g., 60 seconds) during validation to accommodate clock skew. - Improper Refresh Token Rotation: Failing to rotate refresh tokens upon use allows replay attacks. If a stolen refresh token is used, the attacker should be detected. The BFF must issue a new refresh token and invalidate the old one immediately after a successful exchange, as detailed in OAuth 2.0 Best Current Practice.
- Exposing
subClaims in URLs: Passing the user's unique identifier (sub) or other PII in URL query parameters is dangerous. URLs are often logged in server access logs, browser history, and referer headers. Sensitive identity data should always be transmitted in the request body or headers, never in the URL path.
Practical Takeaways
- Always use BFF for mobile: Never implement the full OAuth/OIDC flow directly in a native mobile app. Always route authentication through a Mobile BFF to ensure refresh tokens remain server-side.
- Never store refresh tokens in client-side storage: LocalStorage, IndexedDB, or even in-memory storage on the client are unsafe for refresh tokens. Only the BFF should persist them.
- Validate JWT signatures strictly: Do not rely solely on the presence of a token. The API Gateway and downstream services must cryptographically verify the signature using the IdP's current public keys.
FAQ
Can I skip the BFF for mobile? No. While technically possible to implement PKCE directly in a mobile app, skipping the BFF exposes your refresh tokens to the mobile environment, which is less secure than a dedicated server. The BFF acts as a mandatory security boundary.
How do I handle token expiration? The BFF should handle silent token refreshing. When the BFF detects an expired access token during a request, it uses the stored refresh token to obtain a new access token from the IdP and continues the request without interrupting the user.
Is SSO possible without cookies? Yes. Cross-platform SSO is achieved via the IdP's session management. When the mobile app redirects to the IdP, the IdP checks its own session cookie (set during the web login). If a session exists, the IdP skips the login screen and returns a code to the mobile app, enabling SSO without sharing browser cookies between the web and mobile contexts.
Conclusion
Identity architecture in micro-frontend and multi-platform environments requires a deliberate shift from client-side trust to server-side mediation. The BFF pattern isolates secrets, OIDC enables cross-platform SSO without cookie sharing, and JWT-based validation ensures consistent identity propagation. By treating the BFF as the mandatory gatekeeper and the IdP as the sole authority, architects can build systems that scale without sacrificing security. The trade-off is increased infrastructure complexity, but the alternative—managing credentials in the browser—is a security debt that compounds with every new platform added.
Related posts
Decoding client_secret_basic Default in RFC 8414
An examination of the token_endpoint_auth_methods_supported metadata field in RFC 8414 and why client_secret_basic remains the default authentication method.
Securing gRPC with OAuth2 Token Propagation in Microservices
A guide to securing gRPC services using OAuth2 token propagation and interceptors for reliable microservice communication.
Spring Security SAML Extension: Enterprise SSO Integration
This guide covers enterprise SSO integration using Spring Security SAML, SAML service provider setup, and Spring SAML migration strategies.