Join our Newsletter — 33% off our NHI Course
Home› Guides› OAuth Implicit Flow Migration: Move SPAs to Authorization…
Guide Authorisation

OAuth Implicit Flow Migration: Move SPAs to Authorization Code with PKCE

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 8 November 2026 12 min read
On this page

The OAuth implicit grant puts access tokens in the browser's URL fragment, and the IETF now says clients should not use it, yet many single-page applications (SPAs) and identity provider app registrations still have it switched on. RFC 9700, the OAuth 2.0 Security Best Current Practice, tells clients not to use response type token, the OAuth 2.1 draft removes the grant entirely, and RFC 10017 on browser-based applications calls it deprecated. Browser changes to third-party cookies have also broken the silent renewal that implicit-flow SPAs relied on. This guide is for application developers, identity engineers and security teams. It covers the official positions and dates, how to find apps with implicit enabled in Auth0, Microsoft Entra ID and Okta, the migration to authorization code with PKCE or a backend for frontend, testing and rollback, and the risks of leaving it in place. The standards background is in the OAuth 2.0 Security Best Current Practice (RFC 9700) Guide; this page is the hands-on migration companion.

Key takeaways

  • The standards have moved on. RFC 9700 (BCP 240, January 2025) says clients SHOULD NOT use the implicit grant, and public clients MUST use PKCE; OAuth 2.1 (still an Internet-Draft) does not specify the implicit grant at all.
  • Authorization code with PKCE is the direct replacement. Every major identity provider supports it for SPAs, so most migrations are a library upgrade plus a registration change.
  • A backend for frontend is safer still. RFC 10017 rates the BFF pattern, where tokens never reach the browser, as the most secure option for sensitive applications.
  • Turning off implicit is a separate step. Disable the grant on each app registration only after every client using that client ID has migrated, then keep it off with policy.
  • Implicit-enabled registrations are identity risk. An enabled grant keeps a path open for tokens to be issued in URLs, where they can leak through history, logs or an open redirect on a registered redirect URI, so treat leftover settings as findings.

What is changing and why

The implicit grant (response_type=token, and hybrid variants that return tokens from the authorization endpoint) was designed in 2012 for browser applications that could not make cross-origin calls to a token endpoint. The authorization server returns the access token directly in the redirect URI fragment. That design has several problems that RFC 9700 sets out: tokens can leak through browser history, referrer headers and open redirectors, can be injected by an attacker, and cannot be sender-constrained because there is no standard way to bind a token issued in the authorization response to the client. RFC 9700 section 2.1.2 therefore says clients should not use response type token, or other response types that issue access tokens in the authorization response, unless access token injection is prevented, and should use response type code instead.

The browser constraints that justified implicit have gone: browsers support CORS, so an SPA can call a token endpoint, and PKCE (RFC 7636) protects the authorization code for public clients that cannot hold a secret. Separately, Microsoft's documentation notes that browsers removing third-party cookies break the hidden iframe (prompt=none) renewal that implicit-flow SPAs depend on, because the implicit grant issues no refresh tokens. The flow is now both less secure and less reliable.

Official timeline and current status

There is no single "switch-off" date for the implicit grant across the industry: the standards deprecate it, and each identity provider still supports it for existing apps while recommending migration. Status below was checked on 8 November 2026 on the official pages listed in Standards and references.

SourceDocument and statusPosition on implicit
IETFRFC 9700, Best Current Practice for OAuth 2.0 Security, BCP 240, January 2025Clients SHOULD NOT use the implicit grant; public clients MUST use PKCE
IETFRFC 10017, OAuth 2.0 for Browser-Based Applications, Best Current Practice (BCP 212), August 2026Implicit discouraged and deprecated; authorization code with PKCE is current practice; BFF the most secure pattern
IETFThe OAuth 2.1 Authorization Framework, draft-ietf-oauth-v2-1-17, Internet-Draft dated 31 October 2026, not yet an RFCImplicit grant not specified; removal explained in the draft. Drafts change, so do not rely on draft details.
Auth0Product documentationRecommends authorization code with PKCE for SPAs; implicit with form post only for login-only use (ID token)
Microsoft Entra IDMicrosoft identity platform documentationRecommends not using implicit; new and existing SPAs should use the authorization code flow; MSAL.js 2.x uses authorization code with PKCE
OktaDeveloper documentationRecommends authorization code with PKCE; implicit only for SPAs that cannot support PKCE

Providers are listed alphabetically; the order is not a ranking.

Who and what is affected

  • SPAs built before roughly 2019: apps using older libraries such as MSAL.js 1.x (msal package, UserAgentApplication), ADAL.js or early OIDC client libraries that defaulted to implicit.
  • Server-rendered web apps using id_token responses: sign-in only apps using response_type=id_token with form post. These do not put access tokens in the browser and Auth0 still documents this for login-only use, but they share the same registration setting and should be reviewed.
  • App registrations with the grant enabled but unused: common where a quickstart or template ticked the box years ago.
  • Third-party and internal tools: dashboards, browser extensions and low-code front ends that request tokens directly from the authorization endpoint.
  • APIs that accept those tokens: resource servers trusting bearer tokens issued to implicit clients, often with broad scopes and long lifetimes.

Finding affected systems and identities

Look from both sides: configuration in the identity provider, and actual traffic. Configuration tells you what is possible; logs tell you what is in use.

ProviderWhere implicit is configuredHow to inventory it
Auth0The application's grant_types property; the identifier for the implicit grant is implicitList applications through the Management API or dashboard and flag any whose grant_types include implicit. See the Auth0 Hardening Guide.
Microsoft Entra IDApp registration, Authentication, "Implicit grant and hybrid flows" (Access tokens and ID tokens checkboxes); in Microsoft Graph, the implicitGrantSettings resource with enableAccessTokenIssuance and enableIdTokenIssuanceQuery applications through Microsoft Graph and flag any where either property is true; the portal also shows a warning on Web platform redirect URIs using implicit. See the Entra ID Security Guide.
OktaApp integration, Grant type, "Implicit (hybrid)"; the OAuth client object's grant_types (default authorization_code) and response_types (code, id_token, token, none)List OIDC app integrations through the Apps API or Admin Console and flag any with implicit in grant_types or token in response_types. See the Okta Security Hardening Guide.
  1. Export registrations: pull every application or app integration from each tenant, including development and test tenants, with owner, redirect URIs and grant settings.
  2. Check sign-in and system logs: look for authorization requests with response_type values containing token. Registrations with implicit enabled but no such requests in 90 days can usually be switched off quickly.
  3. Search code: search front-end repositories for response_type=token, id_token token, and imports of deprecated libraries.
  4. Record ownership: each registration is a non-human identity with credentials, redirect URIs and API permissions; assign an owner and review its scopes during the migration. The SaaS and OAuth App Governance Guide covers the wider process.

Migration options

Target patternWhere tokens liveChoose it whenTrade-off
Browser-based client with authorization code and PKCEIn the browser (memory or worker), refresh tokens subject to RFC 9700 rulesLow-sensitivity apps, no backend available, fastest migrationMalicious script in the page can still obtain tokens; XSS defence is critical
Token-mediating backendBackend holds refresh token; browser gets short-lived access tokensA light backend exists and the SPA must call APIs directlyAccess tokens still reachable by browser script
Backend for frontend (BFF)Server side only; browser holds a Secure, HttpOnly session cookieSensitive data, personal data or high-value APIsNeeds a backend that proxies API calls; adds latency and operational work

Decision guidance: for an internal tool with low-impact scopes, authorization code with PKCE in the browser is a reasonable end state. For customer-facing apps, financial or health data, or APIs with write scopes, move to a BFF as RFC 10017 recommends. Small teams often do the PKCE migration first to get off implicit quickly, then plan the BFF as a second step. The pattern detail is in the OAuth for Browser-Based Applications and the BFF Pattern Guide, and PKCE parameters are in the PKCE Implementation guide.

Step-by-step migration to authorization code with PKCE

  1. Upgrade the client library to a version that uses authorization code with PKCE by default. For Microsoft Entra ID, Microsoft's migration guide moves from MSAL.js 1.x (msal, UserAgentApplication) to MSAL.js 2.x (@azure/msal-browser, PublicClientApplication), which uses authorization code with PKCE. Auth0 and Okta SDKs for SPAs use PKCE in their current quickstarts.
  2. Change the registration: in Entra ID, move the redirect URIs that will use the new library from the Web platform to the Single-page application platform, which enables the authorization code flow with PKCE and CORS for those URIs. In Okta, select Authorization Code for the SPA integration; in Auth0, ensure the application's grant types include Authorization Code.
  3. Handle token storage: keep access tokens in memory where possible and avoid localStorage for long-lived tokens. The Browser Storage Security Guide compares the options.
  4. Configure refresh tokens for browser clients with rotation or short lifetimes, as RFC 9700 requires for public clients. See the OAuth Refresh Token Rotation and Expiry Guide.
  5. Tighten the page: a strict Content Security Policy and XSS controls matter more once refresh tokens can reach the browser. See the Content Security Policy Guide.
  6. Disable implicit on the registration only when every production client sharing that client ID has migrated. Microsoft's guide notes that unchecking the implicit settings disables the flow for every app using that client ID.
  7. Prevent regression: add the inventory query to a scheduled check and alert when any registration enables implicit again.

Testing and rollback

  • Run both flows side by side: during migration the registration can allow both implicit (for the old build) and authorization code (for the new build). Release the new build to a pilot group first.
  • Test renewal without third-party cookies: test token renewal in browsers with third-party cookies blocked and in private windows, because this is where implicit-era silent renewal fails.
  • Test sign-out and session expiry: confirm logout clears in-memory tokens and that refresh tokens are revoked or expire as configured. See the OpenID Connect Logout and Session Management Guide.
  • Check the error signal: once implicit is disabled in Entra ID, any client still requesting it receives an unsupported_response error stating that the expected response_type is code. Watch sign-in logs for this error after the switch.
  • Rollback: before implicit is disabled, rollback is redeploying the previous front-end build. After it is disabled, re-enabling implicit should require a time-limited, approved exception, not a quiet configuration change.

Risks of doing nothing

  • Token leakage: access tokens in URL fragments can leak through browser history, logs, referrer headers and open redirects, and RFC 9700 notes there is no standard way to sender-constrain them.
  • Token injection and replay: attackers can inject stolen tokens into a victim's session or replay them at APIs until they expire.
  • Broken sign-in: silent renewal depending on third-party cookies fails in browsers that block them, producing errors that users experience as random sign-outs.
  • Unsupported libraries: older libraries that only support implicit stop receiving fixes, leaving the front end on unmaintained code.
  • Dormant enabled registrations: unused registrations with implicit enabled and loosely controlled redirect URIs widen the paths for token theft; see the Test tenants and legacy app registrations guide for how forgotten registrations feature in incidents.

Detection, metrics and framework mapping

  • Number of registrations with implicit enabled per tenant (trend to zero, alert on any new one).
  • Authorization requests with a token response type per week (target zero after migration).
  • Percentage of SPAs on authorization code with PKCE, and percentage of sensitive apps on a BFF.
  • Number of unsupported_response errors after cut-over, as a signal of unmigrated clients.
  • Percentage of browser clients with refresh token rotation or short lifetimes configured.
FrameworkReferenceRelevance
NIST SP 800-53 Rev. 5IA-5 Authenticator Management; SC-23 Session AuthenticityProtecting tokens as authenticators and preventing session token injection
NIST SP 800-53 Rev. 5CM-7 Least FunctionalityDisabling grant types that are not needed
OWASP ASVS 5.0V10.4.4; V10.6.1Authorization servers allow only the grants a client needs, and the token (implicit) grant and response must no longer be used
MITRE ATT&CK v20T1528 Steal Application Access Token; T1550.001 Application Access TokenTheft and reuse of tokens that implicit-flow designs expose

Practitioner checklist

  • Inventory every app registration in Auth0, Entra ID and Okta tenants, including test tenants, and flag implicit settings.
  • Check logs for token response types and identify which registrations are actually in use.
  • Upgrade SPA libraries to versions that use authorization code with PKCE by default.
  • Move Entra ID SPA redirect URIs to the Single-page application platform.
  • Decide per app between browser-based PKCE and a BFF, using data sensitivity and API scopes.
  • Configure refresh token rotation or short lifetimes for browser clients and keep tokens out of localStorage.
  • Disable implicit on each registration once all clients sharing its client ID have migrated.
  • Schedule a recurring check that alerts when implicit is enabled on any registration.

Standards and references

Related NHI Mgmt Group resources: OAuth 2.0 Security Best Current Practice (RFC 9700) Guide · OAuth for Browser-Based Applications and the BFF Pattern Guide · PKCE Implementation · OAuth 2.1, GNAP and FAPI Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 8 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org