How Backstage sign-in with Keycloak works through generic OIDC
A platform team that already runs Keycloak usually wants developers to sign in to Backstage with the same accounts they use everywhere else. Backstage connects to Keycloak through its generic OIDC authentication provider, not a Keycloak-specific plugin, so Keycloak is treated like any other OpenID Connect issuer. This page covers sign-in only. Importing users and groups from Keycloak into the catalog is a separate task that uses a different plugin and should be planned on its own. Keycloak supports OpenID Connect as one of its protocols, alongside OAuth 2.0 and SAML 2.0, which is what makes the generic module a workable path.
At a high level, the OIDC module redirects the user to Keycloak, receives an authorization code on Backstage's callback, exchanges it for tokens, and then passes the verified identity to a sign-in resolver. Backstage needs three things from Keycloak: a confidential client registered for the Backstage backend, a metadata URL for the realm so Backstage can discover the issuer and endpoints, and a stable claim it can match to a catalog user. Backstage only trusts what it receives from the issuer after the token checks pass, so the realm configuration in Keycloak effectively decides who can sign in. Confirm with your Keycloak administrators which realm, client and mapped claims they will provide before anyone edits the Backstage configuration.
The decision with the largest effect on access is which claim the resolver uses. Email is easy to read and to match against catalog entries, but it can change, and it may not be unique across your identity estate. The sub claim is stable for a given user in a given issuer, but catalog entries rarely carry it, so teams often map it through an annotation or a user reference. Choose one resolver approach, test it with a few accounts including one with no email, and make sure no user can sign in without a matching catalog entity. The Backstage authentication documentation explains why every provider should resolve to the same identity and why guest access should be off in production.
What you need before configuring Keycloak and Backstage
Sign-in between Backstage and Keycloak depends on four parts being in place before any configuration: a Backstage instance on a supported release line, a Keycloak server your team can administer, a realm to hold the client, and a catalog of User entities for the sign-in resolver to match. Confirm each item with the people who own it, because the versions and hosting choices in your environment decide the steps that follow.
Supported Backstage and Node.js
Run Backstage on a release line that the versioning policy still supports, and confirm the Node.js runtime against it. The policy supports exactly two adjacent even-numbered Node.js releases, which Backstage 1.46.0 documents as Node.js 22 and 24. Check the policy for your release line before you pin the runtime in your container image or CI.
A Keycloak server you can administer
Your team needs admin console access and the ability to change client settings, mappers and realm configuration without a vendor ticket. Confirm the Keycloak release you run, since the current release is 26.8.1, and confirm whether it is deployed with the Operator, a Helm chart or a manual install. Operator-managed deployments should be checked against the Operator update approval mode your team uses.
Production database for Keycloak
Keycloak's production databases include PostgreSQL 14 to 18, along with several other engines. The default dev-file database is for development only, so a sign-in path used by Backstage should not depend on it. Confirm which database backs your realm and that the version is inside the supported range before you rely on it for production sign-in.
An existing realm and client plan
Pick the realm that holds your workforce identities and decide who may sign in to Backstage. You will create a confidential OIDC client for Backstage in this realm and set its redirect URI to the Backstage backend, so record the realm name, the base URL and the users or groups in scope before starting. Confirm with your identity team that the realm is the system of record for staff.
User entities in the catalog
The OIDC resolver signs a user in only when it finds a matching User entity in the Backstage catalog. Confirm that your catalog already contains User entities for the people who need access, and that each one carries an email address or a stable identifier that matches the Keycloak claim you plan to use. Without these entities, sign-in fails for the people you intend to admit.
HTTPS and DNS for both sides
Backstage and Keycloak both need stable HTTPS endpoints with DNS names that the browser and the backend can reach. The Backstage backend URL becomes the redirect target, and the Keycloak base URL becomes the metadata source, so an unstable hostname or a mismatched certificate breaks sign-in. Confirm the certificate chain is trusted by the Backstage backend container, not just by the browser.
Configure the Keycloak client and Backstage OIDC provider in sequence
This sequence takes a Keycloak realm from a new confidential client to a working Backstage sign-in button that issues a session. Each step ends with a check so a failure is caught before the next configuration layer depends on it.
Create the confidential client in Keycloak
In the Keycloak admin console, the identity administrator creates an OpenID Connect client in the realm your organization uses for workforce sign-in. Set the client authentication option to on so the client is confidential, and enable the standard authorization code flow. Register the Backstage backend callback as a valid redirect URI, using the path your Backstage version expects for the OIDC provider, which is documented in the Backstage authentication guide. Save the client secret from the Credentials tab into your secret store, not into the repository. The step is done when the client appears in the realm with client authentication enabled and the redirect URI matches your backend's base URL exactly, including the protocol and port.
Copy the realm discovery metadata URL
From the realm settings in Keycloak, the administrator opens the endpoints information and copies the OpenID Endpoint Configuration URL. This URL follows the pattern of the realm base address followed by the well-known OpenID configuration path, and it is the value Backstage uses as the metadata URL. Confirm that the URL matches the public hostname your Backstage backend will reach, because the issuer value inside the document must match the URL you configure. The step is complete when that URL loads in a browser or with curl and returns a JSON document that contains issuer, authorization_endpoint, token_endpoint and jwks_uri fields. If the issuer differs from the hostname you plan to use, fix the Keycloak hostname setting before continuing.
Add the OIDC provider block to app-config
The Backstage platform engineer adds an auth configuration block for the generic OIDC provider under the auth providers section of the backend app-config file. The block sets the client ID, the client secret read from an environment variable rather than a literal value, the metadata URL copied in the previous step, and the callback path. Keep environment-specific values in the environment-specific config file so development and production use different realms. Do not enable guest access in this file. The step is done when the backend starts without a configuration validation error and the auth plugin logs that the oidc provider is registered. If startup fails with a missing secret message, the environment variable is not reaching the backend process.
Install the OIDC provider module in the auth backend
The engineer adds the OIDC provider module package to the backend, then registers it in the auth backend setup so the provider is loaded at startup. The installation is done with the Backstage CLI from the root of the repository, which keeps the package version aligned with the other @backstage packages in use. Next, the engineer checks the Backstage version in use and confirms the module is compatible with it, because auth modules are tied to the core release line. The step is complete when the backend builds and the auth routes respond. A request to the provider's start endpoint should return a redirect to the Keycloak authorization endpoint, which confirms the module is wired correctly.
Set the sign-in resolver
The engineer sets a sign-in resolver for the OIDC provider so Backstage can map the authenticated Keycloak identity to a user entity in the software catalog. The resolver can match on the email claim or on the subject identifier, and the choice depends on whether your catalog user entities carry the Keycloak email or a stable sub value in an annotation. Only resolve identities that have a matching catalog entity, and do not allow sign-in for users who are absent from the catalog. The authentication documentation advises that every provider resolves to the same identity, so confirm the resolver output matches the user reference used by other providers. The step is done when a test user who has a catalog entity signs in and that entity is shown as the session owner. A user without an entity should be refused with a clear error.
Re-badge the sign-in button on the frontend
On the frontend, the engineer configures the sign-in page to show the Keycloak provider with your organization's label and icon. This is done through the sign-in page provider configuration in the app, which lets you set a title and select the provider to display. Use the provider identifier that matches the OIDC provider key in the backend config, because a mismatch leaves the button missing. The frontend and backend should be restarted together so the sign-in page reads the updated settings. The step is complete when the sign-in page shows the relabeled button and selecting it sends the browser to the Keycloak login screen, with no fallback to guest access.
Run a test sign-in and confirm the session
A test user with a catalog entity signs in through the Keycloak button, and the platform engineer checks the result. The browser should return to Backstage, the user's name and profile should appear, and the backend should issue a session that identifies the expected catalog user. Check the backend logs for the sign-in event and confirm there are no warnings about missing claims. Then sign out, sign in with a user who has no catalog entity, and confirm the sign-in is refused. The sequence is complete when both checks pass in each environment, and the results are recorded so a later Backstage or Keycloak upgrade can be tested against the same cases.
How Keycloak identities map to Backstage catalog users
The sign-in resolver is the piece that decides who a Keycloak user is inside Backstage. After the OIDC module completes the login, Backstage has to match the token's identity to a User entity already in the software catalog. If no entity matches, the sign-in fails or, with a poorly chosen resolver, the user gets an identity they should not have. Decide the matching key before you configure anything, because changing it later means re-checking every existing user entity. The custom API ref that the OIDC module creates is the handle the frontend and backend use to reach this provider, so the same resolver logic applies whichever side calls it.
The two common keys are the email claim and the sub claim. Matching on email is simple and works with catalog users created from directory data that holds the same address. The weakness is that email changes when people marry, rename or move domains, and the user then stops matching. The sub claim is the subject identifier Keycloak assigns to each user, and it stays stable for the life of that account, so it is the more durable key. The cost is that catalog entries must carry the matching sub value, usually through an annotation or a populated identity link, so you need an import or sync step that writes it. Confirm the exact claim names your Keycloak client mapper emits, because Backstage resolvers read them from the token and a renamed or missing mapper produces silent mismatches.
Keycloak claims and attributes mapped to Backstage identity fields
This table maps the OIDC claims Keycloak can issue to the Backstage user identity fields and the resolvers that consume them. Read each row as a starting point: which claim is present depends on the client scopes and protocol mappers in your realm, so confirm every mapping against your own realm and catalog data before you pick a resolver.
| Keycloak claim | Backstage use | Dependency in Keycloak | Resolver note |
|---|---|---|---|
| sub | Stable subject identifier for the user | Included in the ID token by default for the OIDC client | Suitable for a resolver that matches on a stable ID, if your catalog stores the same value |
| Matches the catalog user entity email | Needs the email scope and a user with a verified email in the realm | Used by the email-based resolver; confirm your catalog emails match Keycloak exactly | |
| preferred_username | Candidate for the catalog user name | Needs the profile scope; value is editable by users unless locked down | Usually weaker than sub or email as a match key; confirm before relying on it |
| name | Display name shown in the Backstage user menu | Needs the profile scope and a populated first and last name | Display only; not used to match catalog entities |
| Custom attribute (for example, a team or group claim) | Optional extra context for ownership or group membership | Requires a protocol mapper that adds the claim to the token and an agreed claim name | Confirm the claim is present in the token Backstage receives before writing any resolver logic that depends on it |
Securing the Keycloak sign-in path in Backstage
Keycloak sign-in is only as strong as the resolver, secret handling and upgrade routine behind it. The cards below cover the Backstage settings and the Keycloak operating practices that decide who can get into the portal and how the path stays patched.
Disable guest access in production
The Backstage authentication documentation advises against offering guest access in production. Check that no guest provider is enabled in the production app-config and that the sign-in page offers only the Keycloak option. Confirm this in the rendered production config, not only in the base file, because environment overrides are a common place for a guest provider to reappear.
Restrict resolvers to catalog users
Configure the Keycloak sign-in resolver so a user only gets a session when a matching User entity already exists in the catalog. A resolver that creates identities from any valid Keycloak login lets anyone with a realm account sign in. Test with a Keycloak user that has no catalog entity and confirm the sign-in is refused.
Keep the client secret out of Git
The OIDC client secret should come from an environment variable or a secrets store that the deployment injects at runtime, referenced from app-config by name. Keep the value out of the repository, container image layers and CI logs. Ask who can read the secret in Keycloak and in your secrets store, and rotate it on a schedule you record.
Use HTTPS redirect URIs with exact matching
Register the Backstage callback URI in the Keycloak client as an exact HTTPS value, including the path and port. Avoid wildcard redirect URIs and avoid listing development hosts in the production client. Review the valid redirect list and the web origins whenever the portal hostname changes, since a loose entry widens where authorization codes can be sent.
Run Keycloak on a supported release
Keep Keycloak on a release line that the project still supports and read the release notes before each minor upgrade, since minor releases can change behavior in opt-in ways. If Keycloak runs on Kubernetes, install the Operator through Operator Lifecycle Manager and set it to manual approval so an operator update never upgrades the server without a review.
Plan joint patch windows
Backstage and Keycloak both need a planned upgrade window. Backstage ships a monthly main line and weekly next releases, and high and critical vulnerabilities are backported where feasible. Schedule Keycloak and Backstage patches together, test sign-in end to end after each one, and record which release each environment runs so an emergency fix does not surprise the sign-in path.
What Keycloak operational choices affect Backstage sign-in
Keycloak availability sets the ceiling for Backstage sign-in. If the Keycloak endpoints that Backstage calls during login are down, no user can open the portal, and existing sessions cannot be reliably refreshed. Before you wire up the OIDC provider, review the high availability architectures Keycloak documents: a single cluster optionally spread across availability zones, multi-cluster deployments (v2) without external Infinispan, and the deprecated multi-cluster v1 design that used a separate Infinispan cluster per site. Both supported designs depend on a synchronously replicated database, so the database topology is a sign-in decision, not only a Keycloak one. Confirm with your platform team which design fits your recovery targets, and document who owns the database failover runbook.
The database choice is the second decision. Keycloak supports MariaDB, Microsoft SQL Server, MySQL, Oracle Database, PostgreSQL (14 to 18), EnterpriseDB Advanced, Amazon Aurora PostgreSQL and Azure SQL in production. The default dev-file database is for development only, so a Backstage pilot that uses it should not carry into a production sign-in path. Choose a supported engine your database team already operates and can back up and restore. On upgrades, Keycloak migrates its schema automatically at startup by default. Large deployments can instead apply the SQL manually, as the upgrading guide suggests. Decide which mode you will use before the first upgrade, and rehearse it against a copy of production data.
Keycloak plans four minor releases a year and a major release every two to three years. Since Keycloak 26.0, breaking changes in a minor release are opt-in, but you still need to read what your current version changes before you move to the next one. Review the backwards compatibility release notes and the upgrading guide for every version in the path, then check the client settings Backstage depends on, including the redirect URI, client scopes and the sub and email claims your resolver reads. If you run the Keycloak Operator, keep the manual approval mode the project strongly recommends so an operator update cannot upgrade Keycloak without your review.
Common Keycloak OIDC sign-in failures in Backstage
This table pairs each sign-in failure teams commonly hit with its likely cause and the check to run first. Work down the rows in order, since a broken metadata URL or redirect URI blocks everything that follows. Each check points to the setting or log location to inspect in your own environment.
| Failure | Likely cause | Check to run |
|---|---|---|
| Redirect URI mismatch at Keycloak | The callback URL in the Keycloak client does not exactly match the Backstage backend URL, including scheme, host, port and path | Compare the valid redirect URI in the Keycloak client with the backend baseUrl plus the OIDC auth handler path, character for character |
| Metadata URL does not resolve | The metadataUrl points to the wrong realm, has a typo, or the Backstage backend cannot reach Keycloak over the network | Open the metadata URL from the Backstage backend host (for example with curl) and confirm it returns the realm's OpenID configuration |
| Wrong client secret | The secret in the Backstage configuration was rotated in Keycloak or copied from another client | Regenerate or copy the secret from the client's Credentials tab in the correct realm and confirm the environment variable the backend reads |
| Missing email or sub claim | The Keycloak client does not include the email claim or the user has no email attribute, so the resolver has nothing to match | Decode a test token or inspect the userinfo response, and confirm the scopes requested include openid and email |
| Resolver NotFoundError | No catalog user has a matching email or sub, or the catalog user was never ingested before sign-in | Confirm the user exists as a User entity in the catalog with the same email, and check the resolver order in the auth configuration |
| Sign-in button missing after re-badging | The provider ID, the custom sign-in page wiring or the frontend provider import does not match the configured provider | Check that the provider key in the frontend sign-in page matches the backend provider ID and that the custom API ref is registered in the app |
| Login loop or unexpected logout | The sign-out or post-logout URI is not registered in Keycloak, or the session cookie domain does not match the Backstage origin | Verify valid post-logout redirect URIs in the client and confirm the frontend and backend share the same public origin |
Questions teams ask before setting up Keycloak sign-in for Backstage
What drives the effort of Keycloak sign-in for Backstage?
The effort depends mostly on four things: how your Keycloak realms and clients are designed, how user claims map to Backstage identities, how many sign-in resolver rules you need, and how many identity sources sit behind Keycloak. A single realm with one client, a verified email claim and a clear match to existing catalog users is a small job. Multiple realms, brokered providers such as a corporate directory, or users who lack a consistent email or subject value add design work and testing. Each resolver rule needs a test case showing that a sign-in resolves to the intended catalog user and that no one can sign in as someone else. Ask for the number of realms, identity brokers and resolver paths to be listed in the scope before agreeing a timeline.
Can our own team set up Keycloak sign-in for Backstage without a partner?
Yes, a team with Keycloak administration experience and Backstage backend experience can do this in-house. The work involves creating a confidential client, setting the redirect and metadata URLs, configuring the generic OIDC provider in the Backstage app configuration, adding a custom sign-in button and API reference, and writing resolvers that match users in the software catalog. The risk lies in the details: a resolver that trusts an unverified claim, a missing sign-out path, or guest access left enabled in production. A partner is most useful when the team lacks one of these skills, needs a fixed-scope delivery with written verification, or wants a second review of the resolver logic before go-live.
What do we need to provide before the work starts?
You need administrative access to the Keycloak instance or a named administrator who can create realms, clients and mappers. Backstage needs to be running in a non-production environment with its software catalog populated with user entities, because resolvers match Keycloak sign-ins to those entities. A separate test realm with test users is strongly advisable so that claim mapping and resolver behavior can be checked without touching production identities. You also need the hostnames for Backstage and Keycloak, any certificate authority details for internal TLS, and a named owner who can approve the resolver rules. Confirm the exact Keycloak and Backstage versions in your environment before scoping, since the configuration keys can differ between releases.
How long does Keycloak sign-in for Backstage take?
The duration depends on scope rather than on a fixed figure. A single environment with one realm, one client and a simple email-based resolver moves quickly, while several environments, several identity brokers, custom claim mapping and formal test evidence take longer. Time is also consumed by approvals: realm changes, client secret handling and production change windows are often the slowest steps. Ask for a timeline in the written scope that separates design, build in a test environment, verification with test users, and production rollout, and ask which of those steps depend on your change board or on Keycloak administrators being available.
Does this work include importing Keycloak groups into the Backstage catalog?
No. This topic covers sign-in only: configuring Keycloak as the identity provider, mapping a signed-in user to a catalog user, and sending the user into Backstage. Importing users and groups from Keycloak into the software catalog is a separate task that uses a different integration, with its own scheduling, deletion behavior and group-to-team mapping. If you need both, scope them as two pieces of work, because a sign-in that works does not mean the catalog will hold the groups that drive ownership and access. Your engagement scope should name each one explicitly.
What should a quote for Keycloak sign-in for Backstage include?
A written quote should list the scope in concrete terms: the Keycloak and Backstage environments covered, the number of realms, clients and identity brokers, the resolver rules to be built, and the test cases used to prove each one. It should name the deliverables, such as configuration committed to your repository, a short runbook for the sign-in path and a record of test results. It should state what the client provides, what the partner does, and what is excluded, including catalog group import and any Keycloak platform changes such as upgrades. Ask how changes requested after sign-off are handled, and whether ongoing support is quoted separately, since Keycloak and Backstage both release updates that can affect the configuration.
What goes wrong most often with Keycloak sign-in resolvers in Backstage?
The most common failure is a resolver that matches users on a value that is not unique or not verified, so a sign-in lands on the wrong catalog entity. Email matching is only safe when the email claim is verified in Keycloak and the catalog holds the same address. Other common problems include a mismatch between the subject value and the catalog reference, a sign-in that succeeds for a user with no catalog entity, and a re-badged button that still points to a default provider. Test each path with at least one user that exists, one that does not, and one with a mismatched email, and confirm that the unknown user is rejected rather than given an empty identity.
How DeployOpen scopes and delivers Keycloak sign-in for Backstage
DeployOpen plans Backstage sign-in with Keycloak as a fixed-scope piece of work inside your own infrastructure. We agree the realm, client, resolver and sign-in design in writing, then build, test and document it so your team can run it after handover.
How we scope
- We confirm your Keycloak version, hosting model and whether an existing realm and users already exist.
- We agree which resolver strategy maps Keycloak identities to catalog users, including how unmatched users are handled.
- We record the scope, deliverables and timeline in writing before any configuration begins.
How we build
- We configure the Keycloak client with the Backstage redirect URI, scopes and metadata URL in a non-production realm first.
- We wire the generic OIDC provider, custom API reference and sign-in button label into your Backstage configuration.
- We test sign-in by email and by subject identifier, and confirm guest access is disabled outside development.
How we hand over
- We document client settings, configuration keys, resolver logic and the test cases used to verify each sign-in path.
- We walk your platform and security engineers through the configuration and the reasons behind each mapping choice.
- We leave a runbook covering client secret rotation, redirect URI changes and how to revert a failed change.
How we support
- Ongoing support, Backstage version upgrades and Keycloak updates can be covered under a retainer agreed in writing.
- We can review Keycloak upgrade notes and Backstage upgrade changes against your sign-in configuration before each change.
- Retainer scope, response expectations and fees are set in a quote based on the written scope, not a published price list.

