ACUL-based Universal Login cannot be embedded in an iframe due to enforced X-Frame-Options: deny

Hi,

We are building a payments SDK that requires embedding the Universal Login page inside an iframe. We have implemented our login screens using ACUL (Advanced Customizations for Universal Login) with @auth0/auth0-acul-react (v1.0.0).

The Problem

When our application attempts to load the Universal Login page inside an iframe, the browser refuses to render it due to the following HTTP response header being enforced by Auth0’s server:

X-Frame-Options: deny
Content-Security-Policy: frame-ancestors ‘none’

We have confirmed via Auth0’s official documentation that this header is always enforced for New Universal Login (including ACUL) and cannot be disabled:

“The following action is not required if you are using the New Universal Login Experience because those headers are always set in that case.”

Source: Clickjacking Protection for Universal Login Change - Auth0 Docs

Questions

  1. Is there any existing solution or workaround that allows ACUL-based Universal Login to be loaded inside an iframe?
  2. We have also submitted a feature request on GitHub: [Feature Request] Allow ACUL-based Universal Login to be embedded in an iframe · Issue #336 · auth0/universal-login · GitHub Issues · auth0/universal-login · GitHub

We have considered loginWithPopup() and loginWithRedirect() but neither are suitable for our embedded payments SDK use case — popup is unreliable on mobile browsers, and redirect breaks the embedded experience entirely.

We are quite stuck on this and it is currently blocking our development progress. If anyone has faced a similar issue or has any insights — even partial ones — we would truly appreciate your input. Any help, no matter how small, goes a long way. Thank you so much in advance for taking the time to read and respond! :folded_hands:

Any help would be greatly appreciated. Thanks!

Hi @robert.huo

Welcome to the Auth0 Community!

To give you a direct answer: There is no workaround to embed the New Universal Login (or ACUL) inside an iframe. Auth0 enforces the X-Frame-Options: deny and Content-Security-Policy: frame-ancestors 'none' headers at the global infrastructure level for the New Universal Login. This is a strict, non-negotiable security boundary designed to prevent clickjacking, and it cannot be bypassed, overridden, or configured via the dashboard or API.

Since you cannot use an iframe, we need to address the UX constraints of your payments SDK. You mentioned that redirects break the embedded experience and popups are unreliable on mobile.

To move forward, the industry standard to handle this specific payments SDK challenge would be to rely heavily on popups for their web SDKs. Popups are only blocked or become “unreliable” on mobile browsers when they are triggered asynchronously.

->If you trigger the loginWithPopup() method synchronously and directly inside the user’s onClick or onTouchEnd event handler , mobile browsers (including iOS Safari) will reliably allow the popup to open because it is the direct result of a user action.

->If your SDK is being embedded into native mobile applications (iOS/Android) rather than web browsers, you should not be using iframes or web popups at all. The standard approach is to use ASWebAuthenticationSession (iOS) and Chrome Custom Tabs (Android). This securely opens the Auth0 ACUL page over the host app and seamlessly returns control to your SDK without breaking the host app’s state.

->If this SDK is strictly for first-party use (meaning you own both the SDK and the websites it is embedded on), you could theoretically build a completely custom UI in React inside your iframe, and securely pass the user’s credentials back to your server to utilize the Auth0 Authentication API (Resource Owner Password Grant). However, this is highly discouraged, forces you to handle raw passwords, breaks SSO, and prevents the use of standard MFA or Social Logins.

Let me know if you have any other questions on the matter!

Kind Regards,
Nik