How to migrate from Cortex to Backstage without losing ownership data
Catalog data moves from Cortex to Backstage through the Cortex REST API and descriptor files, and the scorecards and any workflows built on Cortex's rule engine need to be rebuilt rather than copied. If your renewal, licensing change, residency requirement or lock-in concern is the trigger, start by inventorying what Cortex holds for you: service entities, owners, groups, dependencies, and the scorecard definitions your teams rely on. Ownership is the data you cannot afford to lose, so treat it as the first item to move and the last item to switch off. Usually a platform engineering or developer experience team leads the work, with a service owner or security engineer validating the scorecard logic and an identity administrator handling who can sign in to the new portal. Confirm the exact export endpoints and fields against Cortex's current API documentation in your account, since the descriptor mapping depends on what your tenant exposes.
Be clear about what you are leaving behind. Self-managed Cortex still requires a license key from the Cortex account team and a PostgreSQL database, so keeping a self-managed instance running during the parallel period means you still pay for the subscription and the infrastructure behind it. Plan for the overlap explicitly: decide how long both portals run, who owns the source of truth for each entity during that window, and what happens when a team changes a service owner in one system but not the other. Backstage itself is Apache-2.0 licensed with no paid edition from the project, so the remaining costs are your own hosting, engineering time, and plugin upkeep. Effort depends mostly on how many entities carry custom Cortex fields, how many scorecards exist, and how many teams depend on Cortex notifications or automations. Ask for a dependency and scorecard inventory before estimating anything, and keep ownership reconciliation reports for each cutover wave so you can prove the catalog matches the source.
Which Cortex capabilities map cleanly to Backstage and which need rework
This table maps the main Cortex capabilities to their closest Backstage equivalents and labels each as clean, needs rework or gap. Use it to scope the migration before you export any data. Plugin coverage changes between releases, so confirm each plugin you plan to rely on against your target Backstage version.
| Cortex capability | Backstage equivalent | Status and what to plan for |
|---|---|---|
| Service catalog components | Software Catalog kind Component in catalog-info.yaml | Clean. Each Cortex service becomes a Component entity. Map the Cortex type and tier fields to entity metadata and tags, and confirm your naming convention before export. |
| Ownership and teams | Group and User kinds, with spec.owner on each entity | Needs rework. Cortex owner data must resolve to Group entities from your identity provider. Configure sign-in resolvers so users map consistently, and verify team membership before cutover. |
| Systems, domains and dependencies | System, Domain and dependsOn or providesApis relations | Needs rework. Cortex groupings and dependency edges must be rebuilt as System and Domain entities with explicit relations. Check that every Component points to a valid System. |
| API definitions | API kind with OpenAPI, AsyncAPI, GraphQL or gRPC definitions | Clean where specs exist. Move the definition files into the repositories and reference them from the API entity. Services with no spec in Cortex will need one written or a documented gap. |
| Documentation | TechDocs: Markdown beside code, built with MkDocs | Needs rework. Cortex-hosted docs are not carried over automatically. Plan to move content into repositories, add mkdocs.yml, and confirm the MkDocs plugins your docs depend on. |
| Scorecards and rules | Tech Insights facts and checks, or custom checks | Gap until rebuilt. Scorecards must be redefined as facts and rule-based checks, then surfaced in plugins. Confirm plugin coverage for each Cortex rule before committing to a date. |
| Initiatives and maturity rankings | No direct built-in equivalent in the core catalog | Gap. Tracking campaigns across teams usually needs custom reporting built on check results. Confirm whether an available plugin covers your initiative workflow. |
| Integrations with CI, source control and incidents | Plugins for GitHub, GitLab, Kubernetes and other tools, plus the catalog processor model | Needs rework. Each Cortex integration must be matched to a Backstage plugin or a custom processor. Confirm coverage for every tool your scorecards read from. |
What data to export from Cortex and which integrations to rebuild
A Cortex to Backstage move is mostly a data and identity exercise. Catalog descriptors, people and group membership, and the integrations that feed them all need a defined home in Backstage before cutover begins.
Catalog entities through the REST API
Start by pulling every entity your teams rely on from Cortex through its REST API, including services, APIs, resources and domains, along with their descriptor fields. Record the count per entity type so you can reconcile it after import. Export the relationships too, such as which service depends on which API, because Backstage expresses these as references between entities rather than as nested fields. Confirm with your Cortex account team which endpoints and access tokens your plan allows before you plan the export window.
Descriptor fields and x-cortex extensions
Cortex-specific fields, including the x-cortex extensions in its descriptors, do not carry over automatically. Build a mapping table that sends each field to a Backstage metadata annotation, a spec property, a tag or a dropped value. Anything you cannot map should be listed as an explicit decision for the owning team, so nothing disappears silently during conversion.
Users and groups for identity mapping
Export the people and team membership that Cortex uses for ownership, then map them to Backstage User and Group entities. Ownership in Backstage depends on the spec.owner references pointing to real groups, so a team that exists in Cortex but not in your directory will leave orphaned components. Ask your identity team which source of truth owns group membership, and decide whether Backstage syncs it from there or from a static file.
Sign-in resolvers across 19 providers
Backstage ships 19 built-in authentication providers, so a single portal can accept sign-in from several identity sources. Configure sign-in resolvers so every provider resolves to the same user identity, otherwise one engineer can appear as two users with split ownership. Avoid guest access in production. Test with a sample of users from each provider before cutover.
Source control and CI integrations
Cortex links services to repositories, pipelines and deployment signals. In Backstage, rebuild these links through annotations on each catalog entity, such as repository location and CI project slug, and enable the matching plugins for the source control and CI systems you run. Check each integration with a test entity, because a wrong annotation will still show a page but no build status.
Alerting and on-call references
Reconnect alerting and on-call data, such as paging service names and escalation targets, to the matching Backstage components. Decide which system remains the source of alert routing, since Backstage displays and links to these references rather than replacing the paging tool. Record each reference during the export so ownership questions can be answered during cutover.
The migration sequence from inventory to decommission
The sequence moves Cortex ownership, service metadata and scorecard logic into a Backstage portal in controlled stages, so each service is verified before the Cortex subscription is ended. Ownership stays authoritative throughout the parallel run, which keeps routing, on-call and scorecard results consistent for both portals.
Inventory Cortex entities and scorecard rules
Platform engineering leads export the current catalog through the Cortex REST API and list every entity type, owner group, custom field and scorecard rule in use. Scorecard criteria, initiatives and any integrations that read Cortex data (CI pipelines, on-call tools, chat alerts) are recorded alongside. The output is a reviewed inventory with one row per entity and one row per rule, signed off by the service owners who will be affected. Confirm the export format and API permissions with your Cortex account team before starting.
Stand up a pilot Backstage instance
The platform team deploys Backstage in your own infrastructure, connects it to your identity provider and sets a PostgreSQL database for the catalog. Authentication should use sign-in resolvers that map each provider to the same user identity, with guest access disabled. The pilot is complete when a small set of services, selected for a range of ownership models, appears in the catalog and a team lead can sign in and view them. Review the Backstage versioning policy first so you pick a release line your team can keep current.
Convert cortex.yaml content to catalog-info.yaml
Engineers map each exported Cortex descriptor to a Backstage entity, choosing the matching kind (Component, API, Resource, System, Domain or Group) and moving owner, lifecycle and relationship data into the metadata and spec fields. Custom Cortex fields are either mapped to annotations or dropped with a recorded decision. API definitions are linked to OpenAPI, AsyncAPI, GraphQL or gRPC files where they exist. The output is a set of catalog-info.yaml files stored next to each repository, and a validation run shows no broken references to owners or systems.
Rebuild scorecard checks in Backstage
The team translates each inventoried scorecard rule into a Tech Insights fact and check, or into a custom check where no plugin covers the rule. Each check is tested against the pilot services and its results are compared with the Cortex scorecard for the same services. Differences are investigated and either fixed in the check or documented as an accepted change. The step closes when every in-scope rule has a passing comparison or a signed exception, and reporting gaps are listed as open work.
Run both portals with ownership synced
Both portals run in parallel for the full set of migrated services. During this phase, ownership is the single source of truth: changes to owners, groups or on-call contacts are made in the source repository descriptor and propagated to Cortex by the sync job, never edited separately in either portal. A reconciliation report compares owner, group and system fields between the two portals on a regular schedule, and teams resolve any drift before it is accepted. The phase ends when the report shows no unresolved differences for the agreed set of services.
Cut over to Backstage as the system of record
Teams move their daily workflows, such as service lookup, ownership questions and scorecard review, to Backstage and update links in runbooks, onboarding guides and integrations. Downstream tools that read Cortex data are repointed to the Backstage catalog and their output is checked against the reconciled data. The cutover is complete when service owners confirm their workflows run in Backstage and no integration still depends on Cortex for ownership or scorecard data.
Decommission the Cortex subscription
After a read-only retention period agreed with your compliance team, the platform team exports a final archive of Cortex data, records where it is stored and who can access it, and removes Cortex integrations and tokens. The commercial agreement is then ended according to its terms, and any self-managed Kubernetes and PostgreSQL resources used only for Cortex are retired. Ask your Cortex account team for the notice period and data return terms in writing before this step starts, and close the step when the archive is verified and the subscription end date is confirmed in writing.
How the migration differs for small, large and self-managed Cortex estates
A small Cortex estate covers a handful of teams and a limited number of services. Inventory is usually manageable by hand, and the export through the REST API can often be reviewed entity by entity. The main effort is deciding which descriptors are worth carrying forward, because a small catalog is a good moment to drop stale components and unused scorecard rules instead of translating them.
- Inventory: List every Cortex entity type in use and confirm which ones have owners, since ownership is what the Backstage catalog depends on most.
- Pilot: Convert one or two well-understood services into
catalog-info.yamlfiles and load them into a test Backstage instance. - Parallel run: Keep Cortex as the reference for a short overlap so teams can compare owners and service details side by side.
- Scorecards: Decide early whether a few rules are enough to rebuild in Tech Insights or whether they can be checked manually during the first cycle.
- Team skills: Confirm that at least one engineer can maintain the Backstage build, since a small team usually has no spare capacity.
Before you start, confirm with your team how many entities actually exist and how many have a named owner, because that count drives the rest of the plan.
A large estate spans many teams, many repositories and several ownership boundaries. Here the inventory is the largest task. Descriptors may live in Cortex only, in source repositories, or in both, and they may disagree. Ownership data often sits in group and user records that must be mapped to identity groups before any entity can resolve correctly in Backstage.
- Inventory: Pull entities through the REST API, then reconcile them against repository scans so that services present in code but missing from Cortex are found before cutover.
- Pilot: Choose pilot teams from different parts of the organization so that naming, group and ownership patterns are tested more than once.
- Identity mapping: Agree sign-in resolvers with your identity team so that each user resolves to one identity, as the Backstage authentication documentation advises.
- Parallel run: Plan a longer overlap with clear owners for each domain, and track which team has signed off on its entities.
- Change control: Freeze descriptor edits in Cortex for each wave, or the export and the Git files will drift apart.
Ask your internal team how many repositories hold services and whether teams already keep ownership files in Git, since that answer decides how much conversion work is automated.
A self-managed Cortex deployment runs in your own Kubernetes cluster, installed from a Helm chart and backed by PostgreSQL. Its data is already inside your infrastructure, so the migration is less about moving data out of a vendor and more about exporting cleanly before the license and the database are retired. The Cortex self-managed documentation also requires a JWT license key and access token from the Cortex account team, so the subscription does not stop when the portal is no longer used.
- Data access: Export entities through the REST API while the deployment is still running, and keep a database backup as a fallback.
- Shared infrastructure: Decide whether the Backstage instance will reuse your existing Kubernetes cluster and PostgreSQL server, or run in a separate namespace with its own logical databases.
- Upgrade path: Compare the Helm-based upgrade cycle you already follow for Cortex with the Backstage release cadence, so you can keep one operating routine rather than two.
- Cutover: Plan the date the license is not renewed, and confirm with the Cortex account team what access remains after that point.
- Security review: Reuse your existing cluster controls for the new workload, and document any change to network access.
Confirm with your platform team which parts of the Cortex Helm release and database you can retire without affecting other systems.
What usually goes wrong when moving ownership data to Backstage
Ownership data is the part of a Cortex migration that teams most often get wrong, because it drives on-call routing, approvals and reporting. The risks below cluster around the parallel run, the translation of scorecards, and the identity and Git practices that keep Backstage's catalog trustworthy after cutover.
Duplicate or conflicting owners
During a parallel run, both Cortex and Backstage show ownership for the same services, and the two records often disagree after teams reorganize. Engineers then page the wrong group or see two owners in different tools. Before cutover, export Cortex owners through the REST API, list every component where the two systems differ, and assign one system as the source of truth for each team. Set a date after which Cortex edits stop, and tell teams where changes must be made.
Scorecards that do not translate
Cortex scorecard rules, levels and initiatives do not map one to one onto Backstage. A rule that depends on a Cortex-specific metric has no direct equivalent, so it can silently disappear and make a service look compliant. Inventory every active scorecard rule and classify each as rebuilt with a Tech Insights fact and check, rebuilt as a custom check, or dropped by decision. Record the owner who approved each drop so that reporting gaps are visible.
Guest access left on in production
Backstage ships with a guest sign-in option that is convenient during evaluation but gives anonymous users access to the catalog. Teams that migrate under deadline sometimes leave it enabled, exposing service names, owners and API definitions to anyone who can reach the portal. The Backstage authentication documentation advises against guest access in production. Before go-live, confirm in the app configuration that guest sign-in is disabled, and test the production URL from an unauthenticated browser session.
Sign-in resolvers that split identities
Backstage has 19 built-in authentication providers, so a team may sign in through GitHub, Okta and a generic OIDC provider. Without a sign-in resolver that maps each provider to one identity, the same engineer can appear as several users, and ownership assigned to one profile is invisible to another. Define a resolver keyed on a stable identifier, such as a corporate email, and test each provider with a user who already owns a catalog entity. Confirm that the User and Group entities in the catalog match the identity provider.
Descriptors drifting out of Git
If catalog-info.yaml files are edited in the Backstage UI or in a copy of the repository, the file in Git and the live catalog diverge, and the next import overwrites someone's change. Ownership then reverts without anyone noticing. Keep every descriptor in the repository that owns the component, require review for changes to the owner and lifecycle fields, and use a scheduled comparison between the catalog and Git to find mismatches. Assign one team to watch the report during the first weeks after cutover.
Stale Cortex sync after cutover
Cortex may continue to receive pushed or scheduled updates from pipelines and integrations that were configured before the migration. Those updates keep changing data that no longer matters, or they re-create records that teams believed were retired. Inventory every integration that writes to Cortex, decide whether each one moves to Backstage, and disable the rest. Keep the Cortex subscription active only as long as the read-only export and audit needs require it, and confirm the end date with your account team.
What drives migration cost and duration
This table lists the main drivers that change the effort of moving from Cortex to a self-hosted Backstage portal, with the reason each one matters and how to keep it under control. Read it as a checklist for scoping, since the Cortex subscription keeps running until cutover and every driver that stretches the schedule adds to that overlap.
| Driver | Why it moves effort | How to keep it down |
|---|---|---|
| Number of entities and teams | Each Cortex entity needs a mapped catalog-info.yaml entity, an owner and a review. Ownership gaps multiply when many teams hold components. | Migrate in waves by domain, and retire stale or duplicate services in Cortex before export. |
| Scorecard complexity | Cortex scorecards with many custom rules must be rebuilt as Tech Insights facts and checks, which often need custom code for rules that have no plugin. | Rank rules by business value, rebuild the top set first, and document any rule dropped. |
| Identity provider setup | Backstage needs an authentication provider and sign-in resolvers that map every login to one identity. Team and group mapping from the existing directory is often the slowest step. | Confirm the directory, group source and sign-in provider early, and avoid guest access in production. |
| Integration count | Each source system Cortex reads from (repositories, CI, incident tools, cloud accounts) needs an equivalent Backstage plugin, processor or scheduled ingestion. | Inventory integrations in Cortex first and mark which ones carry ownership data versus only display data. |
| Documentation volume for TechDocs | Docs stored in other wikis or outside repositories must be moved next to code and built with MkDocs, and broken links or missing navigation must be fixed. | Start with docs that are linked from catalog entities and leave archived pages outside the migration. |
| Internal Backstage development skills | Custom plugins, scorecard checks and upgrade work need engineers who can write TypeScript and follow Backstage's monthly or weekly release lines. | Assign named owners for the portal, budget time for upgrades, or agree a fixed-scope build with an implementation partner. |
| Cutover ownership sync | Ownership changes made in Cortex during the parallel run must reach Backstage, or the two catalogs drift and reviewers lose trust in both. | Freeze ownership edits for a short window at cutover or run a scheduled re-export and diff. |
| Cortex subscription overlap | The Cortex subscription continues until cutover, so every week of parallel running adds recurring licence cost, including for self-managed editions that still need a license key. | Set the cutover date from a written scope, and ask the Cortex account team about renewal terms before committing. |
Questions teams ask before moving from Cortex to Backstage
How much effort and time does a Cortex to Backstage migration take?
No effort or duration figure has been published for this migration, so treat any number you hear as a starting assumption to test. The main drivers are how many services, owners and teams you have, how much of your scorecard logic is custom, how many integrations feed Cortex today, and how much documentation already lives next to the code. A small catalog with few custom rules is far quicker to move than a large one with years of bespoke checks. Ask any partner to base the timeline on a written inventory of your entities, scorecard rules and integrations before work starts.
Can our internal team migrate from Cortex to Backstage alone?
Often yes, if you have engineers who already know TypeScript or React, can run Kubernetes and PostgreSQL, and have a clear owner for the portal. Teams usually struggle less with the export than with the decisions that follow: entity model design, sign-in resolvers, plugin selection and ongoing ownership sync. Be honest about bandwidth, because the portal becomes a product your staff maintain after cutover. If capacity is thin, a fixed-scope engagement from DeployOpen can cover planning, implementation, hardening and documentation while your team keeps ownership.
What skills and staff time does a Backstage migration require?
Plan for four groups of skills: platform engineers to deploy and operate Backstage on your infrastructure, developers to write plugins and custom scorecard checks, data or service owners to validate the converted ownership records, and a security reviewer for authentication and access control. Backstage's authentication documentation advises configuring sign-in resolvers so every provider maps to the same identity and avoiding guest access in production, so an identity specialist is worth involving early. Ask your partner which of these roles they will fill and which must come from your staff.
Does self-hosting Cortex remove the Cortex license cost?
No. Cortex's self-managed deployment still requires a JWT license key and access token from the Cortex account team, so moving the software into your own Kubernetes cluster does not remove the subscription. Self-hosting changes where the data and workloads run, not what you pay for the license. Backstage itself is released under the Apache License 2.0 and has no paid edition from the project, so the software cost moves to infrastructure, staff and any support you buy. Ask Cortex for the commercial terms in writing before you compare the two options.
How are Backstage upgrades handled under its release policy?
Backstage ships a main release line monthly, on the Tuesday before the third Wednesday of each month, and a next release line weekly on Tuesdays, according to its versioning policy. High and critical severity vulnerabilities are backported to releases from the last 6 months where feasible, and other security fixes may be backported. Backstage supports two adjacent even-numbered Node.js releases, which were Node.js 22 and 24 as of Backstage 1.46.0. Budget a recurring upgrade cycle, decide which release line you follow, and confirm whether your partner's support covers upgrades and plugin compatibility.
What should we request in a fixed-scope quote for this migration?
Ask for a written scope that lists every deliverable, the entity types in scope (Component, API, Resource, System, Domain, Group, User, Template and Location), the scorecard checks to rebuild, the identity provider to integrate, and the sync approach used during cutover. Request the assumptions behind the timeline, the acceptance criteria for each deliverable, what your staff must provide, and how rollback works. Also ask who maintains the portal after handover and whether retainers for upgrades, testing or backups are included or priced separately. DeployOpen does not publish a price list, so a quote follows from that written scope.
How do we keep ownership data in sync while we cut over from Cortex?
Run both systems in parallel for a defined period, export Cortex entities through its REST API, convert them into catalog-info.yaml descriptors, and treat the Git repositories as the source of truth once cutover starts. Map Cortex owner fields to Group and User references, and check each team's ownership against its service owners before you retire the Cortex feed. Confirm with your Cortex account team which API endpoints and export formats your version provides, because the exact fields depend on your configuration.
How DeployOpen scopes and runs a Cortex to Backstage migration
DeployOpen plans, implements, integrates, hardens, backs up, documents and supports the Backstage portal inside your own infrastructure, whether that is your cloud accounts, data center or air-gapped network. Most engagements are fixed-scope, so the scope, deliverables and timelines are agreed in writing before any work starts. For a Cortex migration, that written scope should name the entity types being moved, the teams that own each one, the scorecard rules to rebuild, the identity provider that Backstage will sign users in through, and the cutover date. DeployOpen does not publish a price list. A quote follows from that written scope, so the more precisely the inventory is defined up front, the more precisely the quote can reflect the work.
The work is usually split into a discovery step and an implementation step. Discovery confirms what exists in Cortex: the descriptor export, the ownership fields that drive team assignments, and the checks that teams rely on for reporting. Implementation then covers the Backstage deployment, the catalog-info.yaml conversion and import, the scorecard approach (a Tech Insights plugin setup or custom checks), the sign-in resolvers, and the documentation the client's own operators will need after handover. Ongoing support, upgrades and continuous testing are available as a retainer. Backstage is released monthly with a weekly next line, so a retainer or an internal upkeep plan should be part of the scope discussion from the start, not added after cutover. Ask any provider, including DeployOpen, to state in writing which items are one-time and which recur.

