GitHub had 14,000 repositories and fewer than half had clear ownership. When their security team needed to rotate secrets across the organization, they hit a wall: rotating a credential without knowing who owned the repository was risky, often disruptive, and there was no reliable way to route remediation work. In under 45 days, Michael Recachinas and the infrastructure team solved it. Every active repository now has a validated owner, 8,000 abandoned repositories are archived, and the approach is a case study in treating ownership as infrastructure, not process.
The problem: 11,000 unowned repositories and a security bottleneck
GitHub's primary internal organization held over 14,000 repositories by early 2025. More than 11,000 were non-archived, and the vast majority had no clear owner. For repositories attached to production services, the company tracked ownership through its internal Service Catalog. Each service entry recorded the owning team, executive sponsor, and support contacts. But that mapping was many-to-one: a service could attach to only one repository, while a single repository could host multiple services. Starting from a service, you could find the repository and its owners. Starting from a repository, you often found nothing.
That gap became a recurring bottleneck during the secret scanning remediation effort. The security team could technically rotate a compromised secret, but doing so without knowing the repository owner was risky. They had no way to route remediation work. For a one-off effort, that ambiguity is annoying but manageable. For recurring security workflows that fan out across the entire organization, it presents a real operational risk.
The solution: custom properties as ownership infrastructure
The team considered two approaches: storing ownership in a dedicated file within each repository, or maintaining it in a centralized repository. They chose neither. Instead, they used GitHub custom properties, which provided native, structured, and organization-wide metadata without requiring file changes in every repo.
They created two custom properties: ownership-type and ownership-name. The type accepted three values: Service Catalog, Hubber Handle (a GitHub employee), and Team. These covered the realistic range of repository ownership at GitHub. A repository either belonged to a service with an on-call team, a specific employee, or a team with at least two members. The name field was validated against actual organization membership, team existence, and Service Catalog records. If someone typed @my-team instead of my-team, the system accepted it. The goal was frictionless input with robust backend validation.
Before asking anyone to do anything, the team built a periodic sync from Service Catalog to repository custom properties. Every repository that backed a known service had its ownership-type set to Service Catalog automatically. That covered roughly 1,500 service-backed repositories, leaving team repos, documentation repos, one-off projects, and personal experiments remaining.
The rollout: Saturday morning chaos and the 30-day grace period
The team built a GitHub App backed by a Kubernetes CronJob. The enforcement logic needed access to Service Catalog, the GitHub API, and several internal systems, so a simple GitHub Actions workflow was not sufficient. They scheduled the first run for a Saturday morning, thinking nobody would be paying attention. Big mistake.
Issues started appearing in repositories across the organization. People jumped on Slack, asking about this new issue in their repository warning that it would be archived in 30 days if ownership was not set. The initial rollout was noisy, but it was intentional. The team gave everyone a 30-day grace period. After that window closed, any repository that still had no ownership set was archived. Archiving was the deliberate choice because it is reversible and non-destructive: the repository becomes read-only, GitHub Actions stops running, but nothing is deleted. If someone needs it again, unarchiving is straightforward.
The sharp edges: Datadog alerts and stale Service Catalog data
Two incidents during the rollout exposed important edge cases. The first was caused by archiving a repository that Datadog had been configured to monitor. When the repository was archived, Datadog could not create issues in it, which triggered an internal alert. The fix was straightforward: the team added @-mentions of repository administrators and assigned all users with write access as a fallback on ownership issues, ensuring they could not be buried or overlooked.
The second incident was a data reliability problem. The team had built robustness against a Service Catalog outage, but they had not considered that it might return stale or corrupted data. If bad data caused the app to think a batch of repositories had lost their Service Catalog entries, the system would incorrectly flag them for archiving. The mitigation was a low water mark: before performing any actions, the app would tally how many archives it was about to perform and how many issues it was about to open. If the number exceeded a conservative threshold, it bailed out entirely and logged the anomaly for manual review.
Results by the numbers
When the dust settled, GitHub went from approximately 3,000 archived repositories to 11,000. The entire effort took under 45 days from the first run to steady state. Every active repository, roughly 3,000, now has a validated owner. Many of the newly archived repositories had not seen a commit in years: abandoned experiments, completed hackathon projects, and one-person prototypes from 2008.
To make ownership stick, the team enforced the custom properties at repository creation time through every workflow: the repository creation page, internal tooling, and automation. They also tightened the enforcement loop from 30 days to one hour. A new repository that somehow bypassed creation-time ownership requirements gets flagged almost immediately.
What this means for founders and engineering leaders
GitHub solved a problem that every growing organization eventually faces. The approach has three lessons for founders. First, treat ownership as infrastructure, not a process. By embedding it into the platform itself through custom properties, GitHub made ownership a property of the repository rather than a spreadsheet or a ritual. Second, automate the enforcement loop. Without the CronJob and the 30-day deadline, the team would still be chasing repository owners manually. Third, design for reversibility. Archiving instead of deleting meant the team could move fast without fear of permanent data loss. Any founder scaling an engineering organization beyond 50 people will encounter this exact problem. GitHub just showed you how to solve it in 45 days.
