backstage no popup signin
Overview
By default, Backstage opens a popup window for OAuth2/OIDC login. This can be blocked by popup blockers and is a poor user experience. This post covers how to switch to in-window redirect flow using the enableExperimentalRedirectFlow config.
When enabled, unauthenticated users visiting backstage.example.com are automatically redirected to the Keycloak login page without any additional action — no sign-in page, no button click required.
Tested on a custom Backstage 1.48.1 container image with Keycloak OIDC provider.
Problem
Backstage's SignInPage triggers OAuthRequestDialog which calls window.open() for authentication. Users see a popup window for Keycloak login instead of being redirected within the same browser tab.
Solution
Add enableExperimentalRedirectFlow to the root level of app-config.yaml. Introduced in Backstage v1.13.0, this setting makes the auto sign-in path use in-window redirect instead of a popup.
Configuration
For the official Backstage Helm chart, configure as follows:
# charts/backstage/values.yaml
backstage:
appConfig:
# Required: Must be at the root level of appConfig, not under auth.
enableExperimentalRedirectFlow: true
auth:
environment: production
providers:
oidc:
production:
clientId: ${KEYCLOAK_CLIENT_ID}
clientSecret: ${KEYCLOAK_CLIENT_SECRET}
metadataUrl: ${KEYCLOAK_METADATA_URL}
prompt: auto
signIn:
resolvers:
- resolver: emailLocalPartMatchingUserEntityName
dangerouslyAllowSignInWithoutUserInCatalog: true⚠️
enableExperimentalRedirectFlowmust be placed at the root level of appConfig, not underauth:.
Frontend
No code changes needed. Use the standard SignInPage with auto prop:
// packages/app/src/App.tsx
const CustomSignInPage = (props: any) => (
<SignInPage
{...props}
auto
providers={[
{
id: 'keycloak',
title: 'Keycloak',
message: 'Sign in using Keycloak',
apiRef: keycloakOIDCAuthApiRef,
},
]}
/>
);The auto prop triggers login on page load, and enableExperimentalRedirectFlow switches that path from popup to redirect. Combined, an unauthenticated user is immediately redirected to Keycloak on first visit:
Flow: backstage.example.com → Keycloak login → Backstage home
Scope
enableExperimentalRedirectFlow only affects the auto sign-in path. It does not apply to the manual button click path, which still uses popup via OAuthRequestDialog.
| Trigger | Redirect applied | Behavior |
|---|---|---|
| auto prop (page load) | Yes | Redirect |
| Button click (fallback) | No | Popup |
In practice, users rarely see the button since auto fires immediately on page load. The button only appears when auto sign-in fails (e.g., Keycloak outage), where popup-based retry is a reasonable fallback.
Alternatives considered
ProxiedSignInPage
<ProxiedSignInPage {...props} provider="oidc" />Designed for proxy-based auth (header/cookie). Does not work with standard OIDC provider and returns 400 error.
Custom redirect
React.useEffect(() => {
window.location.replace(
`${baseUrl}/api/auth/oidc/start?env=${env}&flow=redirect`,
);
}, []);Works for all cases but risks infinite redirect loops on Keycloak outage and bypasses Backstage's official auth flow.
Comparison
| Approach | Redirect scope | Official | On failure |
|---|---|---|---|
enableExperimentalRedirectFlow | auto only | Yes | Button fallback |
ProxiedSignInPage | All | Yes | 400 error (OIDC incompatible) |
| Custom redirect | All | No | Infinite redirect loop risk |
enableExperimentalRedirectFlow is the recommended approach as it's officially supported and provides safe fallback behavior.
Conclusion
Backstage's default popup-based login is disruptive to developers — popup blockers interfere with sign-in and the extra window breaks workflow. By enabling enableExperimentalRedirectFlow with an OIDC provider like Keycloak, developers are seamlessly redirected to the login page within the same tab, eliminating the popup entirely. This small configuration change significantly improves the developer experience for teams using Backstage as their internal developer portal.