Certified Backstage Associate study materials
Certified Backstage Associate study resources

The Ownership Graph That Never Resolves

Certified Backstage Associate · Put your knowledge to work in context.

All case studies

The Ownership Graph That Never Resolves

Litware has 800 Components and 240 Systems. spec.owner values are GitHub team slugs such as payments-core, but the catalog contains no Group entities for most of them. The ownership card shows 'unknown' and the permission policy that grants payments-core members access to its services never matches. A nightly script generates Group YAML from the GitHub API into a groups repository, but it flattens all teams, drops nested teams, and takes 50 minutes. It also creates Users for only 600 of 1,200 organization members, and 150 contractors are in Microsoft Entra ID but not GitHub. Teams have started adding ad-hoc kind: Group files in their own repositories, which sometimes conflict with the generated ones. The company wants one source of truth for people and teams, nested team structure preserved, and owners to resolve within one hour of a GitHub or Entra change. GitHub is the primary source for engineering teams; Entra ID is authoritative for contractors and employment status.

1. Choose the ingestion architecture. Would you keep the script, use entity providers, or both? Justify with failure modes.

Read the worked answer

Replace the nightly script with entity providers, but do not point two providers at the same User refs. Use the GitHub organization provider for engineering teams and their members, and a Microsoft Graph or Entra provider for contractors and employment status. If the GitHub provider also emits Users, disable user ingestion there or scope it to employees; otherwise the two providers will fight over user:default/<id>. Keep the generated groups repository read-only and migrate exceptions into providers. Entity providers emit full mutations and deletions on a schedule, while the script only appends and cannot represent removal reliably. Run a staging provider against a small organization first, compare entity counts, and only then cut over. One-hour freshness is a schedule decision, not a script runtime problem.

2. How should nested GitHub teams map to Group entities and `spec.members`/`children`? What ownership rule avoids parent-team ambiguity?

Read the worked answer

Map each GitHub team to a stable Group ref, for example group:default/payments-core. Put only direct team members in spec.members; put immediate subteams in spec.children and the parent in spec.parent. Do not flatten transitive membership into every group, because membership changes become expensive and permission decisions become opaque. For ownership, set spec.owner to the team that actually operates the service, usually the leaf team, not the parent organization team. If you need inherited visibility, implement it in the permission policy by walking parent relations, not by duplicating members. Ensure the provider handles renames and cycles, and validate that every spec.owner resolves to a Group or User after ingestion. Add a test fixture with three nested teams and a renamed leaf team.

3. Ad-hoc Group files conflict with generated groups. What governance and technical controls do you put in place?

Read the worked answer

Make providers the only writers for Group and User entities. Remove write access to the generated groups repository and stop accepting ad-hoc kind: Group files from team repositories. If your catalog version supports per-location rules, restrict repository locations to Component, API, System, and Resource; otherwise enforce that in CI with a catalog validation step and a custom processor that rejects Group entities whose managed-by location is not the provider. Keep an exception process with an owner and an expiry. Add alerts for duplicate entity refs, missing owners, and a sudden drop in Group or User counts. This is as much a governance change as a configuration change; without removing the ability to create conflicting groups, the providers will keep losing to ad-hoc files.