Security teams should treat the browser as an untrusted execution environment and avoid leaving access tokens exposed there longer than necessary. A safer design is to minimise token persistence, use standards-based authentication flows, and keep token handling behind a controlled component that can isolate sensitive credentials from browser script access. That reduces the blast radius of XSS and other client-side attacks.
How to think about token handling in a browser-based microservices app
For a single page application, the real question is not whether tokens can be used in the browser, but how much authority the browser ever needs to hold at once. The safest pattern is to keep the browser’s role thin, use standards-based login flows, and avoid making the front end a long-term storage location for credentials that can be replayed against downstream services. OpenID Connect Core 1.0 is the cleanest reference point for separating authentication from application logic.
That design usually means the SPA should request sign-in, receive only the minimum token material needed for the current session, and hand off service calls through a controlled boundary rather than scattering bearer tokens across scripts, storage, and component state. For APIs, audience restriction matters, because a token that is valid for one resource should not become a general passkey for the whole estate. RFC 8707: Resource Indicators for OAuth 2.0 supports that narrower token design.
For most teams, the practical aim is to reduce token visibility, reduce token lifetime, and reduce the number of places where a malicious script could steal or reuse them. That is why many modern designs prefer sender-constrained or proof-of-possession approaches for higher-value sessions, especially when the browser is talking to multiple microservices and token replay would otherwise have broad reach. RFC 9449: OAuth 2.0 Demonstrating Proof of Possession is directly relevant to that control choice.
Why browser token exposure becomes a microservices problem
A SPA rarely talks to just one backend. In a microservices architecture, one exposed access token can open multiple internal paths if the token is accepted too broadly, cached too long, or forwarded carelessly between services. The token handling model therefore becomes an access-design problem, not just a frontend convenience issue.
Bearer tokens are especially sensitive in browsers because any XSS, hostile extension, or compromised third-party script can often read or act on the same runtime context as the application. If the token is persisted in local storage, session storage, or another script-readable location, the attacker does not need to defeat the authentication flow again, only to harvest the existing credential and replay it before it expires.
This is why token lifetime, token audience, and refresh behavior all matter together. Short-lived access tokens reduce replay value, while carefully constrained refresh handling limits how much authority can be renewed from the browser. The more sensitive the microservices behind the app, the more important it is to separate user interaction from credential custody.
What a safer handling pattern looks like in practice
Design the browser to authenticate the user, not to become the durable holder of privileged credentials. A controlled component such as a backend-for-frontend or similar mediation layer can keep sensitive tokens out of JavaScript-accessible storage, centralise outbound service calls, and enforce token audience and session rules before requests reach microservices.
That mediation layer should also make revocation and session termination observable. If the browser can mint, copy, or retain long-lived tokens, the security team loses the ability to contain compromise quickly. If the control point sits server-side, the team can revoke sessions, rotate credentials, and narrow the blast radius without depending on every browser tab to behave perfectly.
When the application must call several services, use scoped tokens for each service boundary rather than one broadly reusable credential. If you are designing for stricter replay resistance, RFC 8705: OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens and RFC 8693: OAuth 2.0 Token Exchange show two different ways to reduce overreach in delegated access.
For teams evaluating their broader token discipline, Token and Session Security Guide, API Key Management Guide, and Secrets Management Guide cover the same core discipline from adjacent angles: keep credentials short-lived, tightly scoped, and hard to expose to untrusted execution paths.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP API Security Top 10 addresses the attack and risk surface, while NIST SP 800-53 Rev 5, OWASP ASVS and CIS Controls v8 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev 5 | IA-5 — Authenticator Management | Token handling depends on secure lifecycle control for access credentials. |
| IA-9 — Service Identification and Authentication | Microservices need authenticated service-to-service token handling and trust boundaries. | |
| AC-6 — Least Privilege | Tokens should carry only the minimum authority needed by the SPA and services. | |
| Recommendation — Use IA-5 to bound token lifetime, rotation, and revocation for browser-issued credentials. Use IA-9 to authenticate service calls without broad bearer-token reuse. Apply AC-6 to scope tokens and service permissions to the minimum required. | ||
| OWASP ASVS | V10 — OAuth and OIDC | SPA authentication flows and token use are directly governed by OAuth and OIDC verification needs. |
| V9 — Self-contained Tokens | JWT and access-token storage, validation, and exposure are central to SPA token safety. | |
| Recommendation — Implement V10 controls to validate OAuth/OIDC token handling and binding choices. Use V9 to constrain token contents, lifetime, and client-side exposure. | ||
| CIS Controls v8 | CIS-6 — Access Control Management | Token scope, revocation, and service access paths are access-control decisions. |
| Recommendation — Apply CIS-6 to remove unnecessary access and revoke overbroad token paths promptly. | ||
| OWASP API Security Top 10 | API2 — Broken Authentication | Improper token handling can directly weaken API authentication across microservices. |
| API5 — Broken Function Level Authorization | A token reused across services can grant functions beyond the intended boundary. | |
| API8 — Security Misconfiguration | Overbroad token acceptance and weak browser storage practices are configuration failures. | |
| Recommendation — Use API2 to prevent replayable or overexposed tokens from authenticating API calls. Use API5 to enforce per-function authorization on every microservice call. Use API8 to harden token acceptance, storage, and CORS-related exposure paths. | ||
Practitioner Guidance
What to verify: Confirm where the access token lives, who can read it, how long it survives, and whether any token presented by the browser is accepted by more than one microservice. If the answer includes local storage, broad audience acceptance, or silent renewal without a strong boundary, the design is too exposed.
Decision rule: If the browser must never see a durable secret, move token custody behind a controlled boundary and treat the SPA as a request initiator, not a token vault. If the service call truly needs browser-held credentials, make the token short-lived, audience-restricted, and replay-resistant.
Common mistake: Teams often harden the login flow but leave the post-login token path weak. That creates a false sense of safety, because the application still fails if a script, browser extension, or injected payload can steal the live token.
Practitioner takeaway: The strongest SPA pattern is usually the one that gives the browser the least reusable authority needed to complete the user journey, while making every token that reaches the browser narrow, short-lived, and difficult to replay.
Related resources from NHI Mgmt Group
- How should security teams protect single-page applications from token exfiltration while preserving a good user experience?
- How should security teams test single-page applications without relying on browser crawling?
- How should security teams implement OAuth in single page applications without exposing tokens in the browser?
- How should security teams handle refresh tokens in single-page applications that run in the browser?