Skip to main content
Version: next
Prime feature only
This feature is only available with a Prime subscription. See plans or contact sales.

Sign-In Providers

Overview how dynamic authentication provider selection works in Backstage on our platform, and how users can configure available login options.

High-Level Overview

Backstage supports multiple authentication providers such as GitHub, GitLab, and OIDC (Keycloak). In kubriX we provide:

  • OIDC / Keycloak is always enabled as the base identity provider.
  • Additional providers (GitHub, GitLab) can be enabled or disabled dynamically through configuration.
tip

The platform reads the configured providers at runtime and only shows those on the Backstage login screen.

Configuration can be fully controlled by the user via *app-config.yaml in the Backstage Helm chart.


Configuring Sign-In Providers

To configure which login buttons appear in the Backstage sign-in page, use the following section in your *values*.yaml:

Example

appConfig:
kubrix:
auth:
allowedProviders:
- github
# and/or
- gitlab

Supported values:

  • github
  • gitlab

OIDC / Keycloak is always active.


Backend Requirements

For each provider you enable in allowedProviders, the Backstage backend must have a matching authentication configuration:

  • GitHub: requires auth.providers.github
  • GitLab: requires auth.providers.gitlab
  • OIDC / Keycloak: already configured on the platform

If a provider is enabled in allowedProviders but not configured in the backend, the login button appears but authentication will fail.


Known Behaviour

  • OIDC provider is always present and cannot be disabled.
  • If no providers are configured, only OIDC will be shown, and backstage logs:
No kubrix.auth.allowedProviders configured. Only OIDC will be shown.
  • Unsupported provider values are ignored but logged in the browser console:
Unknown sign-in providers in kubrix.auth.allowedProviders: bitbucket.
Supported: github, gitlab
  • If the configuration block is missing, Backstage falls back to OIDC only.
  • The feature is modular and ready for extension (e.g. Azure AD, Google Auth) in future versions.

Keycloak User Provisioning

Backstage resolves a logged-in user's identity against the software catalog. When a brand new Keycloak user logs in for the first time, their User entity may not yet exist in the catalog - the Keycloak catalog sync runs on a schedule and may not have run since the user was created.

Without any fallback, this would cause the login to fail entirely.

Opt-In Sign-In Resolver

The kubriX provisioning flow is opt-in via a custom named resolver: kubriXMatchingUserEntityProfileEmail. It is configured alongside the standard Backstage OIDC resolvers and can be switched at any time in *values*.yaml.

The resolver uses a two-step approach:

  1. Try catalog lookup - match the logged-in user's email against spec.profile.email on existing User entities.
  2. Fallback - if no entity is found, issue a temporary token under the user:unprovisioned/ namespace instead of failing.
User logs in via Keycloak


Catalog lookup by email

┌────┴────┐
Found? Not found?
│ │
▼ ▼
Normal login Issue unprovisioned token
user:default/ user:unprovisioned/<username>

Enabling the kubriX Provisioning Flow

In your *values*.yaml, set the resolver to kubriXMatchingUserEntityProfileEmail:

appConfig:
auth:
providers:
oidc:
development:
signIn:
resolvers:
- resolver: kubriXMatchingUserEntityProfileEmail

Using the Default Backstage Behavior

To disable the kubriX provisioning flow and use standard Backstage resolvers instead:

appConfig:
auth:
providers:
oidc:
development:
signIn:
resolvers:
- resolver: emailLocalPartMatchingUserEntityName
- resolver: emailMatchingUserEntityProfileEmail
note

With the default resolvers, login will fail if the user does not yet exist in the catalog. No provisioning dialog will be shown.

The Unprovisioned Namespace

Users who log in before being synced to the catalog receive an identity in the user:unprovisioned/ namespace:

user:unprovisioned/<email-local-part>

This namespace is intentionally separate from user:default/ so that RBAC policies can restrict unprovisioned users to limited access only.

tip

You can use the RBAC backend to define a role for user:unprovisioned/* with minimal permissions while they wait for their catalog entity to be created.

First Login Flow

1. User logs in via Keycloak OIDC
2. No catalog entity found → token issued as user:unprovisioned/<username>
3. Frontend detects unprovisioned namespace → shows "Account Provisioning in Progress" dialog
4. Keycloak catalog sync runs (scheduled, configurable)
5. User entity created in catalog as user:default/<username>
6. Frontend polls catalog every 10s → detects entity creation → dialog switches to success state
7. Re-login button activates → user clicks it → signed out and redirected to login page
8. Second login → catalog lookup succeeds → full identity resolved

Frontend Provisioning Dialog

When a user logs in with an unprovisioned identity, a centered dialog titled "Account Provisioning in Progress" is shown automatically.

While waiting for sync:

Account Provisioning Dialog - waiting state

Once the catalog entity is detected:

Account Provisioning Dialog - ready state

The dialog offers two actions:

  • Dismiss - close the dialog and continue with limited access
  • Re-login - disabled until provisioning is complete, then signs the user out and redirects to the login page
note

The dialog checks the catalog immediately on open, then every 10 seconds. Once the user:default/<username> entity appears, it automatically switches to the success state and activates the Re-login button - no manual refresh needed.

Catalog Sync Schedule

The time a user waits depends on the Keycloak catalog sync frequency. The default is 30 minutes. You can shorten this in your *values*.yaml:

appConfig:
catalog:
providers:
keycloakOrg:
default:
schedule:
frequency:
minutes: 5
timeout:
minutes: 3
tip

For a better first-login experience, set the frequency to 5 minutes. Avoid values below 2 minutes for large Keycloak realms as the sync may not complete before the next run starts.

Summary

StateIdentityAccessDialog shown
First login, not yet synceduser:unprovisioned/<name>Limited (RBAC)Yes
After sync, re-loginuser:default/<name>Full Granted (RBAC)No