How Backstage gets Okta users and groups for catalog ownership
Owners in the Backstage catalog only work if they match people who exist in Okta, yet sign-in and organization data are configured as two separate pieces. The platform team needs to decide where users and groups come from for catalog ownership, and then confirm that sign-in can find the matching entity. Backstage's integrations documentation lists Okta among its providers, separately from the Okta authentication provider. That separation matters: the integration is the route for reading Okta data into the catalog, while the sign-in provider only handles who can log in.
The docs describe the supported method for pulling Okta users and groups into the catalog, and the team should follow the current page for the exact module and configuration keys rather than relying on names recalled from older guides. Confirm the method, the Okta API token or application credentials it requires, and which Okta groups will become catalog groups before any build work starts. Also confirm the sync schedule, since that determines how quickly a new hire or a changed team owner appears in the catalog.
The Okta sign-in provider does not create users. Its resolvers, such as emailMatchingUserEntityProfileEmail and emailMatchingUserEntityAnnotation (using the okta.com/email annotation), look up an existing user entity, so a person who signs in before their user entity exists will not resolve. Plan the order of operations: load org data first, check that a sample of users and groups appear with the expected emails, then enable sign-in with a resolver that matches those entities. Write down which field is the join key, because a mismatch in email casing or an alias will break sign-in and ownership at the same time.
What you need before connecting Okta to Backstage
Connecting Okta as a source of org data touches a Backstage version choice, an Okta tenant, network paths and a database. Settle these before writing any provider configuration, because each one decides how the catalog ownership model gets built and kept current.
Backstage version line
Choose between the main line, which ships monthly, and the next line, which ships weekly. Main suits teams that want fewer upgrades; next suits teams that want fixes sooner and can absorb more frequent changes. Per the versioning policy, high and critical vulnerabilities are backported to releases from the last 6 months where feasible, so plan to stay on a supported release. As of 1.46.0, Node.js 22 and 24 are the supported pair, so confirm your runtime image matches before you install the Okta module.
Okta tenant and API client
Create an Okta application that the Backstage backend uses to read users and groups. This is a machine-to-machine client, separate from the application users sign in through. Confirm the exact app type, required API scopes and any admin consent steps in the Okta provider documentation, because these change how the client is granted access. Record which groups are in scope so the read permissions stay as narrow as the catalog needs.
Network path to Okta
The Backstage backend, not the browser, calls the Okta API during ingestion, so the backend host needs outbound HTTPS to your Okta domain. Check egress rules, proxies and any allowlists in your cloud account or data center. If Backstage runs in an air-gapped or restricted network, confirm with your Okta administrator how the tenant is reached before the design starts.
Okta user and group model
Review how users, groups and emails are set up in Okta before ingestion. Ownership in the catalog depends on each person having a stable email and on group membership reflecting real teams. Identify duplicate accounts, service accounts and contractors who should or should not appear as owners. Decide which Okta groups map to catalog groups, and who approves changes to that mapping.
PostgreSQL for the backend
Backstage uses PostgreSQL in production and gives each backend plugin its own logical database through Knex, so the catalog state lives there rather than in SQLite. Provision a database the Backstage backend can reach, with backups and a restore owner assigned. Ingested users and groups are stored in this database, so confirm who operates it and how it recovers from failure before the first sync.
Separate sign-in from org data
Okta sign-in and Okta org data are configured independently, even when they share a tenant. Sign-in resolvers match a successful login to an existing catalog user, so the user entities must already exist. Plan which credentials back each path, keep them in your secrets manager, and confirm that sign-in does not depend on the ingestion job succeeding.
Why org data and sign-in are configured as two jobs
Org data and sign-in are two separate jobs, and they only work together when they agree on who each person is. Importing organization data from Okta creates user and group entities in the Backstage catalog, which is what makes ownership, team pages and template permissions possible. The Okta authentication provider does something different: it verifies a person at login and then has to find the matching user entity in the catalog. If the import and the sign-in disagree about identity, a person can sign in successfully and still have no catalog entity to attach to, or land on a different user than the one who owns their services.
The link between the two is the sign-in resolver. The Okta provider docs describe resolvers such as emailMatchingUserEntityProfileEmail, which matches the sign-in email against the catalog user's profile email, and emailMatchingUserEntityAnnotation, which matches against the okta.com/email annotation. Either way, the user entity must already exist, so the import has to run before anyone relies on sign-in. Confirm which resolver fits your data: the profile email is the simpler option, while the annotation suits cases where the catalog email differs from the login identifier. The Okta authentication provider documentation lists the current options.
The Backstage authentication documentation advises configuring resolvers so that every provider resolves to the same identity, and it recommends not offering guest access in production. For this topic, that means testing one account end to end: the user is imported, signs in through Okta, resolves to the same entity that owns their services, and no guest path bypasses that check. Plan that test before go-live, and decide who owns resolver changes, since a resolver edit can silently change which catalog entity a sign-in maps to.
Configure Okta org data in Backstage step by step
This sequence takes you from a read-only Okta credential to a verified catalog of Okta users and groups, and then to a sign-in resolver that matches those entities. Each step ends with a check so ownership in the catalog can be confirmed before sign-in is switched on.
Create a read-only Okta application and credentials
An Okta administrator creates a dedicated service application in the Okta admin console for Backstage, grants it only the read permissions needed to list users and groups and their memberships, and records the Okta domain and client credentials. Use a separate application from the one that will handle sign-in so that revoking one does not break the other. Confirm the scope with your Okta administrator and your security team before continuing. Done when the application exists, its permissions are documented, and a test read of the user list succeeds with those credentials outside Backstage.
Store Okta secrets outside app-config
The platform team places the Okta domain-specific secret values in your secret store or in environment variables injected at runtime, and references them from the Backstage configuration by name. Keep the values out of app-config files and version control, and limit read access to the Backstage backend workload. Confirm that the configuration file contains only placeholder references by searching the repository for the secret value. Done when a deployed backend resolves the variable at startup and no plaintext credential appears in committed files.
Add the Okta integration and org data ingestion
A Backstage developer adds the Okta integration block to the backend configuration and registers the Okta org data entity provider in the catalog backend, with the schedule and the user and group filters your organization needs. Start with a narrow group filter so the first import stays small. Check the Backstage integrations documentation and the Okta provider documentation for the exact configuration keys in your release. Done when the backend starts without configuration errors and logs show the provider is registered.
Run the first import into a non-production catalog
The team runs the import against a non-production Backstage instance backed by its own database so that any mapping mistakes stay out of production ownership data. Trigger a refresh or wait for the scheduled run, then review the backend logs for the number of users and groups processed and for any skipped records. Keep a record of the filters used so the import can be reproduced. Done when the logs show a completed run with no unexplained errors.
Confirm user and group entities and membership
A catalog reviewer looks up several known people and teams by name in the Backstage catalog and confirms each user entity has the expected email, display name and group membership. Open a group entity and check that its members match the groups in Okta, and confirm that a disabled or removed Okta user does not appear as active after a refresh. Compare a sample against the Okta console directly. Done when the sample matches Okta and an ownerRef on a test component resolves to an imported group.
Configure the Okta sign-in provider and resolver
Once the imported entities are verified, a Backstage developer adds the Okta authentication provider with a separate client application, sets the sign-in resolver to match the imported user entities (for example by email), and turns off guest access for this environment. Use the Okta authentication provider documentation for the exact resolver names available in your release. Done when the configuration loads and the resolver is listed in the auth configuration without guest access enabled.
Test sign-in with a non-admin account
A tester signs in to the non-production Backstage with a standard Okta user account that is not an administrator, then checks that the session resolves to the matching imported user entity and that group-based ownership shows the expected components. Repeat with one user who has no catalog entity to confirm that sign-in is refused rather than creating an unmanaged identity. Record the results and the resolver used. Done when both test cases behave as expected and the results are approved before the configuration moves toward production.
How Okta users, groups and profiles map to catalog entities
This table compares each Okta object with the Backstage catalog entity it becomes and the field that carries it. Read it to decide which Okta attributes must be populated for ownership and the sign-in resolver to match. Confirm the exact field names against the Okta entity provider version you install, since mappings can change between releases.
| Okta object | Backstage entity and field | Resolver or match role | Confirm before go-live |
|---|---|---|---|
| User profile email | User entity metadata.name and spec.profile.email | Primary match key for emailMatchingUserEntityProfileEmail | Okta email is the value sign-in resolves against |
| Okta user ID or login | User entity annotation tied to the Okta user | Alternative match via okta.com/email annotation | Check which annotation key your provider version writes |
| Display name | User entity spec.profile.displayName | Display only, not used for matching | Confirm the attribute the provider maps to displayName |
| Manager | User entity spec.manager reference | Used for reporting lines, not sign-in | Confirm whether your provider populates manager or needs a custom transformer |
| Custom profile attributes | User entity custom annotations or spec fields via a transformer | Optional, only if a resolver uses them | Map each attribute explicitly in your transformer configuration |
| Okta group membership | User entity spec.memberOf referencing Group entities | Controls team ownership of catalog entries | Confirm group filters so only ownership-relevant groups are imported |
| Okta group | Group entity with spec.type and metadata.name | Targets for owner references in catalog-info.yaml | Group names must match what teams write in ownership fields |
| Parent and child groups | Group entity spec.parent and spec.children | Shapes the hierarchy used in ownership views | Okta nesting is flattened in some setups, so verify the result in a test catalog |
Choosing the matching key and group scope
The sign-in resolver needs a way to connect an Okta identity to a user entity in the catalog. Matching on email is the simplest option because the email address is usually present in both places and is already unique within your organization. Matching on an annotation, such as the okta.com/email annotation on the user entity, moves the link into the catalog descriptor, so you control the value even when the Okta email differs from the address people use to sign in or from the address in other systems.
- Email matching: Requires no extra catalog metadata, but fails silently when an email changes on one side only, when aliases exist, or when contractors use personal addresses.
- Annotation matching: Lets a platform team set the link explicitly, which helps with renamed staff and shared mailboxes, but every user entity must carry the annotation and someone must keep it current.
- Maintenance load: Email matching shifts work to the identity team's data hygiene. Annotation matching shifts work to whoever generates or edits user descriptors.
- Ownership accuracy: Both approaches can be accurate. The question is which failure you would rather detect early, a mismatched email or a missing annotation.
- Mixed approach: Some teams use email for most users and annotations as an override for exceptions, which keeps the descriptor small while covering edge cases.
Before deciding, ask your identity team how reliably email addresses are maintained in Okta and whether the Okta provider documentation for your Backstage version lists the resolvers you plan to use.
Okta groups can number in the thousands, while only a subset usually matters for ownership. Importing every group gives the catalog complete visibility into the directory and makes group-based access rules easy to write. Importing only groups that map to teams, business units or owners keeps the catalog focused, reduces noise in group pickers and limits the number of groups that must be reviewed when names change.
- Full import: Every Okta group becomes a Backstage group, which is simple to explain but exposes temporary, role-based and application-specific groups that no one owns.
- Filtered import: Only groups with a naming convention, a prefix or a membership in a designated Okta group are imported, which keeps ownership meaningful.
- Group hierarchy: Decide whether parent and child groups should map to Backstage group parent relationships, since flattening can hide reporting lines.
- Maintenance: A filter is one more rule to version and review, but it prevents ownership pickers from filling with stale groups.
- Drift risk: Group names that change in Okta can break filters, so agree on a stable naming convention with the identity team before you build the filter.
Confirm the group filter options your Okta integration supports against the Backstage Okta provider documentation before you commit to a naming scheme.
A person can authenticate with Okta and still have no matching user entity in the catalog, for example when a new hire signs in before the org data import has run, when a contractor has an account but no team, or when an entity is removed from the catalog while the Okta account remains active. The sign-in resolver decides what happens next. Failing closed rejects sign-in until the catalog matches, which protects the catalog from unexplained users but can block legitimate staff. Allowing sign-in with a minimal identity keeps people productive, but those users have no ownership and may gain access to features that assume a catalog entry.
- Reject sign-in: Strongest control for ownership accuracy, but it depends on import timing and produces support tickets for new joiners.
- Create a placeholder user: Keeps access working while flagging the account for review, though placeholders can linger without owners.
- Guest or default access: Backstage advises against guest access in production, so this option should not be used for workforce sign-in.
- Monitoring: Whichever path you choose, report users who signed in without a catalog match so the gap is visible.
- Offboarding: Deactivated Okta users should lead to catalog removal or ownership reassignment, otherwise orphaned entities accumulate.
Check with your security and identity teams which behavior your access policy requires, and test the resolver with a user who has no catalog entry before rollout.
Securing the Okta credentials and the sign-in path
Backstage holds two separate Okta relationships: a client that reads users and groups into the catalog, and a sign-in provider that maps people to those catalog entities. Each needs its own access, secret handling and logging, and both must be reviewed together because a resolver mistake can attach a person to the wrong owner.
Least-privilege read access for the org data client
The catalog import should use an Okta API service account that only reads users and groups. Grant the read scopes the org data module needs and nothing that changes users, group membership or applications. Confirm the exact scopes and admin role requirements in the Okta provider documentation for your Backstage version, and record which Okta admin approved the grant. A compromised read client then exposes directory data but cannot alter who owns what.
Secret storage and rotation
Keep the Okta client secret or private key out of app-config.yaml and load it from your secret manager or a Kubernetes secret at runtime. Give the import client and the sign-in application separate credentials so one can be rotated without breaking the other. Set a rotation schedule, test it in a non-production instance, and confirm that old credentials are revoked in Okta once Backstage picks up the new value.
Disabling guest access in production
Remove any guest or development sign-in provider from production configuration. Guest access lets anyone reach the portal without an identity that maps to a catalog user, which defeats ownership checks and makes audit trails meaningless. The Backstage authentication documentation advises against guest access in production, so treat its presence in a production config file as a finding to fix before go-live.
Restricting sign-in to catalog groups
Limit who can sign in by requiring that the user already exists as a catalog entity, and by restricting access through the groups that the import populated. A resolver such as emailMatchingUserEntityProfileEmail only succeeds for users present in the catalog, so an Okta account that was never imported cannot obtain a portal identity. Decide which Okta groups are imported at all, since the import scope also defines the sign-in boundary.
Reviewing resolver behavior after changes
A change to the import filter, the email attribute or the resolver can silently reassign ownership. After any change, sign in with a test account from each Okta group and confirm the resolved entity, owner and group memberships match the expected person. Repeat the check when you change the Okta app, the email claim or the okta.com/email annotation, because those inputs drive the match.
Logging import and sign-in events
Record each catalog import run, including the number of users and groups added, changed or removed, and record each sign-in with the resolved catalog entity. Keep these logs in a system that the portal team cannot quietly edit. Ask your logging and security team which retention period applies to identity events in your environment, then align the Backstage log destination and Okta System Log retention to that requirement.
Why sign-in fails or ownership drifts after the Okta import
This table lists the failures teams most often hit after importing Okta users and groups into Backstage, with the likely cause, the check to run and the fix for each. Read it when sign-in is rejected or catalog ownership no longer matches Okta, and work down the rows in order of the symptom you see.
| Failure | Likely cause | Check and fix |
|---|---|---|
| Sign-in rejected with no matching user | The sign-in resolver looks for a User entity that the Okta import never created, often because the user is outside the import filter or the import has not run yet. | Confirm the user exists as a User entity in the catalog. Widen the import filter or run the import, then retry sign-in. Confirm the resolver's email lookup matches the attribute the import writes. |
| Duplicate users from email case or aliases | Okta and the sign-in provider present the same person with different email case or a secondary alias, so two User entities match different lookups. | List User entities that share a normalized email. Pick one canonical email in the Okta profile, align the resolver's lookup with it, and remove the duplicate entity. |
| Groups missing from ownership | The group import filter excluded the Okta group, or the group was never mapped to a Group entity that owners can reference. | Check whether the Okta group passes the import filter and appears as a Group entity. Adjust the filter, re-import, and update the owner references in catalog descriptors to point at the Group entity. |
| Stale membership after Okta changes | Membership is written on import and the catalog does not reflect later Okta changes until the next scheduled run, so removed or moved users keep their old groups. | Compare a sample user's Okta groups with the catalog record and note the last successful run. Shorten the schedule if the gap is unacceptable, and confirm that removed memberships are cleared on the next run. |
| Import credential or permission errors | The Okta API token or service credentials are expired, revoked, or lack the read scope needed to list users and groups. | Review the import logs for authorization failures. Rotate the credential, confirm it has read access to the users and groups in scope, and store it in the secrets mechanism your deployment uses. |
| Import cannot reach Okta | Network rules, a proxy, or DNS on the Backstage backend block outbound calls to the Okta tenant URL. | Test outbound connectivity from the backend host or container to the tenant domain. Open the required egress path or configure the proxy, then rerun the import. |
| Sign-in works but ownership is wrong | Sign-in and the import resolve identities differently, so a person signs in as one entity while owning another. | Compare the signed-in user's entity reference with the owner references in the catalog. Align the resolver and the import on the same identifier before correcting ownership. |
Questions buyers ask before connecting Okta to Backstage
Who pays for configuring, testing and maintaining the Okta org data integration?
Your organization pays for the Okta tenant, the Backstage hosting and any licenses, while the engineering labor is paid to whoever builds the integration, either your internal team or an implementation partner. A fixed-scope engagement is priced from a written scope that lists the directory objects, resolver logic, test cases and handover work. Recurring costs include the time your team spends reviewing group changes, rotating the Okta application credentials, and applying Backstage upgrades. Ask any quote to separate one-time build work from ongoing support so you can compare it with an internal estimate.
What makes the Okta org data work larger or smaller?
The main drivers are the number of users and groups to import, how cleanly group membership maps to the teams that own catalog entities, and how many sign-in resolvers you need to keep identities consistent. A directory with clear group naming and a single email attribute per person is much simpler than one with nested groups, duplicate accounts or contractors without profiles. Each additional provider you sign in with also adds resolver work, because every provider must resolve to the same catalog user. Filters that limit which Okta groups are imported reduce both build and test effort.
How long does the Okta org data integration take to build?
Duration depends mainly on directory size, how many group filters you need, and how complex the resolver logic is, so there is no fixed timeline that applies to every organization. A small, well-named directory with one resolver usually moves faster than a large tenant with exceptions, delegated administration and multiple sign-in methods. Your schedule should be set after a short discovery step that inventories the Okta objects in scope and the owners who will check results. Ask for the timeline to be tied to written milestones in the scope document.
What does our team need to provide before the work starts?
You need administrator access to the Okta tenant, or a named administrator who can create the application and grant read access to users and groups. A separate test tenant or sandbox group set lets the team check imports and resolver results before anything reaches production. You also need owners for each team or system who can confirm that the imported groups match real ownership, and a Backstage environment where the integration can run. Agree on who approves Okta credential creation and who receives the rotation schedule.
Can an internal team set up Okta org data alone?
Yes, an experienced internal team can build it if it has Backstage configuration skills, Okta administration experience and time to test. The work sits in the catalog and sign-in configuration, so the team must understand how user entities must exist before Okta sign-in can resolve a person to a catalog entity. Teams without prior Backstage work often spend longer on resolver behavior and on verifying that ownership matches the directory. A partner can cover the design, build and handover, while your team keeps operating the integration afterward.
Why must user entities exist in the catalog before Okta sign-in works?
The Okta sign-in provider resolves a signed-in person to a catalog entity through a resolver such as matching the email profile or the okta.com/email annotation, so the user entity has to be present first. If the catalog has no matching user, sign-in can fail or the person can appear without the groups and ownership they need. Keeping org data and sign-in on the same identity source avoids two sets of users that drift apart. Check the Okta authentication provider documentation before you finalize which resolver your sign-in will use.
How do Backstage upgrades affect the Okta integration?
Backstage upgrades move all @backstage packages together with yarn backstage-cli versions:bump, so the Okta-related modules must be checked as part of each bump. The Backstage Upgrade Helper shows template changes between versions, which helps your team see where configuration or code may need edits. Because high and critical security fixes are backported to recent releases, a planned upgrade cadence is needed to stay supported. Ask whether your integration is covered by the upgrade scope and test it in a staging environment before each production change.
Can we keep Okta sign-in and Okta org data on separate configurations?
Yes, sign-in and org data are configured separately, so you can change one without rebuilding the other, but they must still agree on identity. The sign-in provider needs the resolvers that connect each login to a catalog user, while the org data import creates those users and groups. Guest access should not be offered in production, so every person should come through a resolved identity. Document both configurations together so an engineer can see which settings affect ownership and which affect login.
Where to read the Backstage integrations and Okta docs
Start with the Backstage integrations documentation, which lists Okta among the providers that can feed organization data into the catalog. That page is the right place to confirm which integration settings apply to your Backstage version and how the Okta entries sit alongside the other providers. Keep it separate in your notes from the Okta authentication provider page, because the two cover different jobs: one populates users and groups, the other handles sign-in and resolves a signed-in person to a catalog user entity. Reading both before the design review keeps the team from mixing their settings.
Then read the Okta authentication provider page, focusing on the resolver options such as emailMatchingUserEntityProfileEmail and emailMatchingUserEntityAnnotation. Those resolvers depend on user entities already existing in the catalog, so the sign-in page is where you check the dependency your org data design must satisfy. Confirm on the provider page which Okta settings and resolver names apply to your Backstage release, and record the version you checked, since configuration keys can change between releases. Your team should also confirm the current Okta setup requirements with your own Okta administrator, because those depend on your tenant.
Before the review, write down three questions to answer from these pages: which Okta data the integration reads, which resolver your sign-in will use, and where the two configurations must agree. Bring the Backstage version you plan to run, since the release line you pick affects which documentation applies. Treat the pages as the reference for what to verify in a test environment, not as a substitute for that test.
How DeployOpen scopes and delivers the Okta org data integration
DeployOpen is a Chainscore Labs company that plans, implements, hardens, documents and supports self-hosted open-source platforms inside your own infrastructure. For Backstage and Okta org data, we scope the user and group import, the sign-in resolver design and the verification steps in writing before any build begins.
How we scope
- Confirm which Okta organizations, groups and user attributes feed Backstage ownership and which stay out of the catalog.
- Document how each Okta user maps to a catalog user entity and which field serves as the matching key.
- Agree in writing how sign-in resolvers stay separate from the org data import and which sign-in paths are in scope.
How we build
- Configure the Okta integration and the scheduled user and group ingestion in your Backstage backend.
- Test that group membership produces the expected ownership on sample components in a non-production instance.
- Validate that Okta sign-in resolves to the same catalog user that the org data import created, without guest access.
How we hand over
- Deliver configuration, credential handling notes, resolver rules and a runbook for the ingestion schedule.
- Walk your platform and identity teams through ownership checks and how to diagnose a missing user or group.
- Record the agreed scope, deliverables and open decisions so later changes are tracked against the written baseline.
How we support
- Engagements are fixed-scope, and ongoing support, upgrades and continuous testing are available as a retainer.
- Review the integration when Backstage releases change the Okta provider or when Okta tenant settings change.
- Confirm with your team the upgrade path for Backstage packages, so the org data integration moves with the rest of the portal.

