A developer portal cannot compensate for a catalog that names the wrong owner, omits important systems, or leaves dead services looking active. Every plugin that joins incidents, deployments, costs, security findings, or documentation to catalog entities amplifies the underlying metadata. The right recovery sequence is therefore catalog first, integrations second. These Backstage catalog best practices focus on restoring confidence in identity, ownership, lifecycle, and ingestion before expanding the portal.
Backstage describes the Software Catalog as a centralized system for software ownership and metadata, commonly using descriptor files stored with code and harvested into the catalog. That model gives teams a familiar Git workflow, but it does not guarantee truth. Repositories can be undiscovered, descriptors can be copied, groups can be stale, processors can reject entities, and owners can approve metadata without accepting operational responsibility. Repair begins by defining what the catalog is allowed to claim.
Define trustworthy catalog outcomes
Write a small set of user-facing questions the catalog must answer: What software exists? Which team is accountable now? What system and domain does it support? Is it experimental, production, deprecated, or retired under local definitions? Where are its source, runbook, telemetry, and support channel? Which APIs and resources does it provide or consume? A field is required only if a real workflow depends on it and an accountable source can maintain it.
Define accuracy, completeness, freshness, and integrity separately. A present owner field may be inaccurate. A correct record may be incomplete for incident response. A once-correct lifecycle can become stale. A valid entity may point to a nonexistent relation. Give each critical field an authoritative source, evidence, refresh expectation, and remediation owner. Avoid a single quality score that lets optional labels offset a missing production owner.
| Dimension | Test | Evidence | Failure action |
|---|---|---|---|
| Coverage | Expected software has an entity | Repository, runtime, cloud, or registry inventory | Create, exclude with reason, or investigate |
| Identity | Entity reference is stable and unique | Canonical namespace, kind, and name rule | Merge duplicates or rename through migration |
| Ownership | Named group accepts accountability | Group directory plus owner attestation | Route to resolver; never invent an owner |
| Freshness | Critical facts were recently verified | Source timestamp and observed evidence | Mark stale and prompt owner |
| Relations | System graph resolves without orphans | Processed relations and target entities | Fix source reference or approved boundary |
Assign a source of truth for each field
Do not declare the whole YAML file authoritative when its fields originate elsewhere. The repository may own description and API relations; the identity directory may own groups and membership; the service-management system may own criticality; runtime discovery may prove deployment; finance may own cost center. Document precedence and conflict behavior field by field. If an automated provider overwrites repository metadata silently, teams will stop correcting either source.
Backstage supports entity providers and processors for external integrations. Providers operate at the catalog edge and can make full or delta updates to the bucket they own; processors participate in repeated processing and can transform or emit child entities. Prefer a provider when an external system owns a set of entities and deletions must be represented deliberately. Use processors for parsing, validation, enrichment, and relationships. Give every provider a stable unique name and monitor its last successful synchronization.
Build an independent inventory and reconcile coverage
Create an expected-software inventory from multiple signals: source organizations, deployment targets, package registries, cloud accounts, API gateways, databases, on-call schedules, and spend. Normalize likely identity keys without automatically merging records. Compare this inventory with processed catalog entities and classify gaps: legitimately excluded, missing descriptor, ingestion failure, duplicate identity, retired asset, or unknown. The reconciliation process should be repeatable so coverage does not decay after the cleanup project ends.
Use discovery integrations where they can enumerate repositories consistently, but control scope. Scanning every repository may import experiments, forks, archived projects, and infrastructure helpers as production components. Define eligibility rules and explicit exclusions. Record why an asset is out of scope and when that decision expires. A catalog that hides unmanaged production software to keep its completeness number high is more dangerous than one that visibly reports unresolved inventory.
Stabilize entity identity and the system model

Backstage entity references combine kind, namespace, and name. Establish naming rules before bulk import, and do not use display titles as identifiers. Decide how repositories containing multiple deployables map to components, how shared resources are represented, and when a component belongs to a system. Backstage's model includes domains, systems, components, APIs, resources, groups, users, and templates; use only distinctions that support navigation, ownership, or automation.
Repair duplicates through an explicit mapping from old references to canonical references. Update relationships, annotations, links, dashboards, and plugin data before removing the old entity. Consider a temporary alias or redirect in consumers that support it. Never delete and recreate a production entity casually: external systems may have stored its reference, and historical evidence can become detached. Track identity changes as migrations with owners and completion checks.
| Entity field | Minimum rule | Common defect | Repair evidence |
|---|---|---|---|
| metadata.name | Stable machine identifier under naming policy | Repository rename creates a second entity | Canonical mapping and consumer search |
| spec.owner | Resolvable group accepting accountability | Person, mailing list, or vanished team | Current group attestation |
| spec.lifecycle | Locally defined supported value | Every component marked production | Runtime and owner confirmation |
| spec.system | One meaningful system boundary where applicable | Organizational chart used as architecture | Architecture owner review |
| links and annotations | Target exists and has a maintained purpose | Copied stale dashboard or repo URL | Automated reachability plus owner check |
Turn ownership and lifecycle into evidence
Ownership means authority and obligation, not familiarity. The owning group should be able to approve changes, receive operational escalation, maintain metadata, and arrange support. Validate that spec.owner resolves to a current group and periodically ask that group to attest its entities. For shared platforms, separate service ownership from infrastructure dependency; naming every consuming team as owner destroys accountability. Unowned entities should enter a visible resolution queue rather than being assigned to the platform team by default.
Define lifecycle values operationally. production might require a live deployment, accountable group, support route, recovery expectations, and maintained runbook. deprecated should include replacement and target retirement date. retired should require runtime absence and preserved historical evidence. Backstage accepts lifecycle as a string in component specifications; the organization supplies meaning and validation. Keep the vocabulary small enough that teams apply it consistently.
Expose processing failures and stale entities
A descriptor committed to Git is not necessarily a usable catalog entity. Monitor unprocessed entities, provider failures, processing latency, rejected descriptors, unresolved relations, and location errors. Route failures to the source owner with the exact location and validation reason. Backstage documents an Unprocessed Entities feature for diagnosing processing problems; operationalize it as a queue with age, owner, and service objective rather than checking it only during incidents.
Staleness needs positive evidence. Repository activity alone is insufficient because stable services may change rarely, while abandoned systems can still receive automated commits. Combine owner attestation, deployment observation, endpoint or package evidence, on-call mapping, and source status. Mark uncertain entities as stale without deleting them. Before removal, check runtime, dependencies, audit retention, and external references. Deletion should follow retirement, not substitute for it.
Run quality as a product program
Publish dashboards by defect class and business workflow: production entities without owners, incident services without catalog links, stale criticality, broken relations, and processing failures. Show trends and time to repair. Sample records manually to estimate false confidence in automated checks. Give teams a low-friction pull request or form to correct data, then feed recurring defects back into templates, providers, and validation rules.
Roll out enforcement in stages. First observe and explain. Then warn owners in their normal workflow. Finally reject new or changed production descriptors missing truly mandatory fields while allowing controlled remediation for legacy records. A catalog gate should return an actionable message and identify the policy owner. Do not block urgent service changes because an unrelated optional metadata field is empty.
Key takeaways
- Define which operational questions the catalog must answer before requiring fields.
- Reconcile catalog entities against independent software inventories.
- Assign authority and precedence field by field across repositories and external systems.
- Require ownership acceptance and operational lifecycle definitions.
- Treat processing failures, stale records, and identity migrations as operated queues.
Frequently asked questions
Should catalog metadata live only with source code?
No single location is authoritative for every fact. Keep developer-owned metadata near code, but ingest directory, runtime, risk, or finance facts from their accountable systems. Define precedence and expose provenance so users know where to correct an error.
How should unowned services be handled?
Place them in a visible resolution queue, use repository, deployment, on-call, and organizational evidence to find an accountable group, and require acceptance. Temporary escalation ownership can coordinate remediation, but it should not falsely become permanent service ownership.
When is the catalog ready for more plugins?
When the entities needed by that plugin have reliable identity, ownership, and relations, and processing failures are operated. Readiness can be scoped: a deployment plugin may launch for a verified cohort while unresolved legacy assets remain visibly outside its assurance boundary.
Conclusion
Catalog repair is not a YAML cleanup. It is the creation of an evidence-backed model connecting software, accountable groups, architecture, and operating state. Once sources, identity, ownership, lifecycle, ingestion, and staleness have explicit rules, integrations become trustworthy rather than decorative. That foundation lets a developer portal answer real questions at the moment teams need them.