GitHub ha explicado cómo abordó internamente un problema frecuente en organizaciones con muchos repositorios: conseguir que cada repositorio activo tuviera un propietario duradero. Según el caso publicado por GitHub, el punto de partida era una organización con más de 14.000 repositorios y menos de la mitad con una propiedad clara. En menos de 45 días, el equipo identificó propietarios para repositorios activos y archivó repositorios que ya no debían permanecer como activos.
La lección no está solo en la escala. Está en el enfoque: el ownership de repositorios no se trató como una etiqueta administrativa, sino como una base operativa para seguridad, mantenimiento y gobierno.
Para organizaciones que usan GitHub como plataforma central de ingeniería —aplicaciones, infraestructura como código, librerías internas, automatizaciones, pipelines MLOps o repositorios de IA— un repositorio sin propietario no es un detalle menor. Es una deuda operativa que afecta a la respuesta ante vulnerabilidades, a la revisión de pull requests, al mantenimiento de dependencias, a la gestión de secretos y a la capacidad de tomar decisiones rápidas cuando algo falla.
En entornos cloud y DevSecOps, el ownership de repositorios debería considerarse un control fundacional. Igual que no desplegaríamos una suscripción de Azure sin responsables financieros, técnicos y de seguridad, tampoco deberíamos operar un repositorio activo sin un equipo capaz de responder por su ciclo de vida.
Qué significa tener un propietario duradero
Asignar un propietario a un repositorio no consiste en escribir el nombre de una persona en una descripción. Ese enfoque suele romperse cuando alguien cambia de equipo, abandona la compañía o deja de mantener el componente.
Un propietario duradero es una entidad organizativa estable, normalmente un equipo, con responsabilidad explícita sobre el repositorio durante todo su ciclo de vida.
La diferencia entre un owner nominal y un owner duradero es importante:
- Un owner nominal puede ser quien creó el repositorio hace años.
- Un owner duradero es quien puede decidir si el repositorio sigue siendo necesario, priorizar correcciones, revisar cambios sensibles, responder a alertas de seguridad y aceptar o rechazar cambios relevantes en su arquitectura.
En GitHub, esta idea puede apoyarse en equipos, permisos, archivos CODEOWNERS, reglas de protección de ramas y herramientas de seguridad de aplicaciones. No obstante, conviene evitar una confusión habitual: “propietario duradero” no es una funcionalidad concreta que se active con un botón en GitHub. Es un modelo operativo que puede implementarse usando capacidades existentes de la plataforma y procesos internos de gobierno.
Cuando el ownership es fiable, el resto de controles puede apoyarse en él. Cuando no lo es, muchos procesos se convierten en ruido: alertas que nadie atiende, pull requests bloqueadas por revisores inexistentes o repositorios críticos que nadie se atreve a archivar.
El problema de fondo: repositorios huérfanos
Los repositorios huérfanos aparecen gradualmente. Un equipo crea una prueba de concepto, una librería interna o una automatización temporal. El código funciona, alguien lo reutiliza y, con el tiempo, se convierte en dependencia de otros sistemas. Después cambian los equipos, se pierde el contexto original y el repositorio queda vivo, pero sin propietario claro.
Este patrón es habitual en organizaciones que han crecido rápido o que han adoptado GitHub como plataforma transversal. También aparece en iniciativas de IA, donde se crean repositorios para notebooks, evaluadores, conectores, pipelines de ingesta, prompts versionados o prototipos de agentes. Si esos activos llegan a producción, aunque sea de forma indirecta, necesitan gobierno operativo.
Un repositorio huérfano introduce varios riesgos:
- Falta de respuesta ante vulnerabilidades. Si Dependabot, secret scanning o code scanning generan alertas, alguien debe decidir si la corrección es urgente, si requiere pruebas adicionales o si el repositorio puede archivarse.
- Acumulación de permisos. Sin owner, nadie revisa si los colaboradores actuales siguen necesitando acceso.
- Ambigüedad en los cambios. Una pull request sobre un componente sin dueño puede quedar bloqueada o aceptarse sin revisión adecuada.
- Ruido operativo. Repositorios sin uso pueden seguir generando issues, alertas y expectativas de soporte.
- Riesgo de dependencia invisible. Un repositorio aparentemente abandonado puede estar siendo consumido como plantilla, submódulo, paquete interno o fuente de documentación operativa.
En el caso descrito por GitHub, el objetivo fue eliminar esa ambigüedad a escala. El proceso no se limitó a etiquetar repositorios, sino que distinguió entre repositorios activos que necesitaban owner y repositorios que podían archivarse. Esa segunda parte es clave: asignar propietarios a repositorios que ya no deberían estar activos solo traslada el problema.
Inventario antes que automatización
El primer paso para resolver el ownership es construir un inventario fiable. Antes de hablar de CODEOWNERS, reglas de ramas o políticas de seguridad, hay que saber qué repositorios existen, cuáles están activos, quién los usa y qué señales permiten inferir responsabilidad.
Un inventario útil no se limita al nombre del repositorio. Puede combinar señales como:
- estado del repositorio: activo o archivado;
- visibilidad: público, privado o interno, según el tipo de cuenta y plan;
- actividad reciente;
- último push;
- lenguaje principal;
- rama por defecto;
- pull requests abiertas;
- issues abiertas;
- workflows de GitHub Actions;
- paquetes publicados;
- dependencias declaradas;
- alertas de seguridad;
- relación con despliegues o servicios en producción;
- equipos o personas con acceso.
En organizaciones con Azure, también puede ser útil correlacionar repositorios con recursos desplegados, grupos de recursos, suscripciones, identidades administradas, service principals o pipelines de infraestructura. Esa correlación no siempre existe de forma automática, pero puede construirse a partir de convenciones de naming, metadatos internos, pipelines y catálogos de servicio.
La actividad reciente es una señal útil, pero no suficiente. Un repositorio puede no tener commits recientes porque es una librería estable, pero seguir siendo crítico. Del mismo modo, un repositorio con actividad reciente puede ser una prueba interna sin uso real. Por eso el inventario debe combinar señales automáticas con validación humana.
GitHub GraphQL API permite consultar muchos metadatos de repositorios de forma estructurada. El siguiente ejemplo muestra una consulta base para obtener repositorios de una organización con información útil para iniciar una clasificación.
import os
import requests
GITHUB_TOKEN = os.environ["GITHUB_TOKEN"]
ORG = os.environ["GITHUB_ORG"]
query = """
query($org: String!, $cursor: String) {
organization(login: $org) {
repositories(first: 50, after: $cursor, orderBy: {field: UPDATED_AT, direction: DESC}) {
pageInfo {
hasNextPage
endCursor
}
nodes {
name
nameWithOwner
url
isArchived
isPrivate
updatedAt
pushedAt
primaryLanguage {
name
}
defaultBranchRef {
name
}
}
}
}
}
"""
headers = {
"Authorization": f"Bearer {GITHUB_TOKEN}",
"Accept": "application/vnd.github+json",
}
cursor = None
repos = []
while True:
response = requests.post(
"https://api.github.com/graphql",
json={"query": query, "variables": {"org": ORG, "cursor": cursor}},
headers=headers,
timeout=30,
)
response.raise_for_status()
payload = response.json()
if "errors" in payload:
raise RuntimeError(payload["errors"])
data = payload["data"]["organization"]["repositories"]
repos.extend(data["nodes"])
if not data["pageInfo"]["hasNextPage"]:
break
cursor = data["pageInfo"]["endCursor"]
for repo in repos:
language = repo["primaryLanguage"]["name"] if repo["primaryLanguage"] else "unknown"
default_branch = repo["defaultBranchRef"]["name"] if repo["defaultBranchRef"] else "none"
print(
repo["nameWithOwner"],
repo["isArchived"],
repo["updatedAt"],
repo["pushedAt"],
language,
default_branch,
)
Este script no decide ownership por sí solo. Su valor está en crear una base de trabajo verificable: una lista de repositorios con señales iniciales de actividad y estado. A partir de ahí, se pueden añadir columnas como equipo sugerido, owner validado, criticidad, decisión de archivo y estado de revisión.
Nota: En una organización grande, el inventario debe ejecutarse con credenciales y permisos adecuados, siguiendo el modelo de seguridad interno. Para procesos recurrentes de auditoría no conviene depender de tokens personales sin gobierno.
Clasificar: activo, candidato a archivo o incierto
Una vez disponible el inventario, el siguiente paso es clasificar. La clasificación evita tratar todos los repositorios igual. Un repositorio con despliegues activos, dependencias internas y alertas abiertas requiere un proceso distinto al de una prueba de concepto sin commits en dos años.
Una clasificación inicial puede usar tres estados:
- Activo. Repositorios con uso claro, commits recientes, workflows activos, paquetes publicados, despliegues asociados o dependencia conocida desde otros sistemas.
- Candidato a archivo. Repositorios sin señales de uso, sin despliegues conocidos y sin dependencias relevantes identificadas.
- Incierto. Repositorios donde las señales técnicas no bastan para tomar una decisión segura.
La categoría “incierto” es especialmente importante. En muchas organizaciones, el error no está en automatizar poco, sino en automatizar decisiones con señales incompletas. Archivar un repositorio puede romper procesos si alguien lo consume como dependencia, plantilla, submódulo o fuente de documentación operativa.
Por eso conviene combinar heurísticas con ventanas de revisión. Un proceso razonable puede ser:
- detectar repositorios sin owner validado;
- proponer clasificación automática basada en señales;
- notificar a equipos potencialmente relacionados;
- abrir una ventana para objeciones o confirmaciones;
- validar owner o aprobar archivado;
- registrar la decisión.
Este proceso no necesita ser perfecto desde el primer día. Lo importante es que sea repetible, trazable y suficientemente claro para que los equipos sepan qué se espera de ellos.
Validar owners: la parte humana del sistema
El punto más difícil del ownership no es técnico. Es organizativo. La automatización puede sugerir responsables, pero la propiedad debe ser validada por equipos reales. Esa validación es lo que convierte una etiqueta en un compromiso operativo.
Un buen proceso debería pedir a cada área que confirme tres cosas:
- si reconoce el repositorio;
- si acepta responsabilidad sobre él;
- si el repositorio debe seguir activo.
Si un equipo reconoce el repositorio pero no quiere mantenerlo, la conversación debe pasar a priorización: migrarlo, transferirlo, archivarlo o asignar capacidad de mantenimiento. Lo que no debería ocurrir es dejar el repositorio activo sin responsable.
También conviene evitar asignaciones primarias a individuos. Una persona puede figurar como contacto operativo, pero el owner duradero debería ser un equipo. Los equipos sobreviven mejor a rotaciones, reorganizaciones y cambios de disponibilidad.
En GitHub, esta responsabilidad puede representarse mediante equipos de la organización y reforzarse con CODEOWNERS. Según la documentación de GitHub, un archivo CODEOWNERS permite definir personas o equipos responsables de partes del código. Cuando se abre una pull request que modifica archivos cubiertos por esas reglas, GitHub puede solicitar revisión a los propietarios correspondientes. Para exigir esas revisiones, debe combinarse con reglas de protección de ramas que requieran aprobación de code owners.
Un ejemplo sencillo:
# Owner por defecto del repositorio
* @contoso/platform-engineering
# Infraestructura como código
/infrastructure/ @contoso/cloud-platform
# Workflows de CI/CD
/.github/workflows/ @contoso/devops-enablement
# Componentes de seguridad y autenticación
/src/security/ @contoso/application-security
# Documentación operativa
/docs/runbooks/ @contoso/site-reliability
Lo importante del ejemplo no es solo la sintaxis, sino el modelo. El owner por defecto evita zonas sin responsable, mientras que las rutas específicas asignan revisiones a equipos con contexto.
Importante:
CODEOWNERSsolo es efectivo si los equipos mencionados existen, tienen acceso suficiente al repositorio y las reglas de protección de ramas exigen revisión de code owners cuando sea necesario. Un archivo correcto sin políticas asociadas puede generar una falsa sensación de control.
Archivar también es gobernar
Una de las decisiones más relevantes del proceso descrito por GitHub fue archivar repositorios que no debían seguir activos. Archivar no es borrar. Es declarar que el repositorio ya no está en mantenimiento activo y reducir su superficie de cambio.
En la práctica, el archivado ayuda a evitar que componentes abandonados sigan aceptando modificaciones, acumulando issues o generando expectativas de soporte. También reduce ruido para los equipos de seguridad y plataforma.
El archivado debería tener criterios claros. Por ejemplo, un repositorio puede ser candidato a archivo si:
- no tiene owner validado;
- no presenta señales de uso activo;
- no tiene despliegues conocidos;
- no se identifica como dependencia de otros sistemas;
- no existe una razón documentada para mantenerlo activo.
Antes de archivar, conviene comunicar la intención durante una ventana razonable y permitir objeciones justificadas. En organizaciones reguladas o con dependencias complejas, el archivado debería dejar trazabilidad:
- quién aprobó la decisión;
- qué señales se revisaron;
- qué equipos fueron consultados;
- cómo reactivar el repositorio si fuese necesario;
- dónde queda registrada la decisión.
Esa trazabilidad puede almacenarse en un issue, una discusión, una herramienta interna de gobierno, un catálogo de servicios o una base de datos operativa.
El archivado también tiene valor para seguridad. Cada repositorio activo puede contener secretos, workflows, dependencias vulnerables, configuraciones obsoletas o permisos heredados. Reducir el número de repositorios activos disminuye el ruido y permite concentrar la atención en lo que realmente está en uso.
Ownership como base para seguridad de aplicaciones
Cuando cada repositorio activo tiene un owner validado, muchas prácticas de seguridad se vuelven más efectivas.
Las alertas de dependencias pueden enrutarse al equipo correcto. Las revisiones de código sensible pueden exigir aprobaciones adecuadas. Los secretos expuestos tienen una ruta de escalado clara. Las excepciones de seguridad pueden asociarse a un responsable que entiende y acepta el riesgo.
Este punto es fundamental en plataformas con muchos equipos. La seguridad central no puede conocer el contexto de cada repositorio ni priorizar cada vulnerabilidad de forma aislada. Su papel suele ser definir políticas, proporcionar herramientas, detectar desviaciones y ayudar en la remediación. El owner del repositorio aporta contexto:
- si el componente está expuesto a Internet;
- si forma parte de un flujo crítico;
- si tiene despliegues activos;
- si contiene datos sensibles;
- si puede actualizarse sin impacto;
- si puede archivarse.
El ownership también mejora la calidad de las métricas. Sin owners fiables, métricas como “alertas abiertas por equipo” o “tiempo medio de remediación” son poco útiles. Con owners duraderos, la organización puede medir exposición, priorización y cumplimiento por dominios reales de responsabilidad.
En entornos de Azure, este modelo encaja bien con landing zones, plataformas internas y modelos de operación cloud. Una arquitectura madura no solo define redes, identidades, políticas y observabilidad; también establece quién opera cada carga de trabajo y quién responde cuando aparece un riesgo.
Repositorios de IA: ownership más allá del código tradicional
El enfoque también aplica a repositorios de IA. En algunos casos, incluso con más urgencia.
Un repositorio de IA puede contener:
- prompts versionados;
- datasets de evaluación;
- scripts de ingesta;
- conectores;
- configuraciones de modelos;
- pipelines de fine-tuning;
- evaluadores automáticos;
- lógica de orquestación de agentes;
- definiciones de índices o estrategias de recuperación para sistemas RAG.
Muchos de esos elementos evolucionan rápido y pueden afectar al comportamiento en producción sin parecer “código de aplicación” en el sentido tradicional.
En sistemas RAG, por ejemplo, el repositorio puede contener conectores, transformaciones, definiciones de índices, pipelines de chunking o configuración de recuperación. Si nadie es owner, resulta difícil saber quién debe responder ante una degradación de calidad, una fuga de información, una dependencia vulnerable o un cambio de comportamiento provocado por una actualización de datos o configuración.
La propiedad duradera también ayuda a evitar que los prototipos se conviertan en producción accidental. Si un repositorio de experimentación empieza a ser consumido por otros equipos, el cambio de estado debe ser explícito. Debe pasar de “sandbox” a “activo”, con owner, documentación mínima, controles de seguridad y criterios de soporte.
Un modelo práctico para implantar ownership
Una organización no necesita tener 14.000 repositorios para sufrir este problema. Con unas pocas decenas ya pueden aparecer repositorios sin dueño, especialmente si varios equipos comparten una misma organización de GitHub.
La clave es diseñar un proceso repetible, no una limpieza puntual.
Un modelo práctico puede seguir estos pasos:
- Extraer inventario de repositorios. Incluir metadatos técnicos y señales de actividad.
- Identificar repositorios sin owner validado. Separar ausencia de metadatos de ausencia real de responsabilidad.
- Clasificar repositorios. Activo, candidato a archivo o incierto.
- Validar con equipos. Confirmar responsabilidad, necesidad de mantenimiento y estado del repositorio.
- Actualizar controles. Permisos, equipos,
CODEOWNERS, reglas de ramas y documentación mínima. - Archivar lo que no deba seguir activo. Con ventana de revisión y trazabilidad.
- Convertirlo en control continuo. Revisiones periódicas y validación obligatoria para repositorios nuevos.
Después de la primera campaña, el proceso debe integrarse en el ciclo de vida normal:
- cada repositorio nuevo debería requerir owner desde su creación;
- cada cambio de equipo debería revisar los repositorios asociados;
- cada repositorio sin actividad durante un periodo definido debería entrar en revisión;
- cada excepción debería tener una justificación y un periodo de revisión;
- los owners deberían sincronizarse con catálogos de servicio o plataformas internas cuando existan.
Una forma sencilla de formalizarlo es mantener un archivo de metadatos en el repositorio, además de CODEOWNERS. No existe un estándar universal para este archivo, pero muchas organizaciones usan convenciones internas para alimentar catálogos de servicio o developer portals.
schemaVersion: 1
name: payments-api
description: API interna para operaciones de pagos
owner:
team: platform-payments
contact: [email protected]
lifecycle: production
criticality: high
dataClassification: confidential
links:
runbook: https://example.com/runbooks/payments-api
serviceCatalog: https://example.com/catalog/payments-api
Este archivo no debe contener secretos ni datos sensibles. Su función es hacer explícito el contexto operativo mínimo del repositorio. Integrado con automatización, puede servir para validar que todo repositorio activo tiene owner, ciclo de vida, criticidad y enlaces operativos básicos.
Nota: Los nombres de campos del ejemplo son ilustrativos. Cada organización debería adaptarlos a su catálogo de servicios, herramientas de gobierno y modelo de equipos.
Métricas que sí importan
El éxito de una iniciativa de ownership no debería medirse solo por el porcentaje de repositorios con un campo owner rellenado. Esa métrica puede ser necesaria, pero es insuficiente.
Lo importante es si el ownership mejora la operación.
Algunas métricas útiles son:
- porcentaje de repositorios activos con owner validado;
- número de repositorios archivados tras revisión;
- tiempo medio para asignar owner a repositorios nuevos;
- porcentaje de alertas de seguridad con equipo responsable;
- tiempo de remediación por equipo;
- repositorios con
CODEOWNERSválido; - repositorios críticos con protección de ramas;
- repositorios activos sin actividad reciente y sin revisión documentada;
- excepciones abiertas y próximas a caducar.
La métrica más reveladora suele ser la reducción de “nadie sabe”. Si ante una vulnerabilidad crítica, una dependencia comprometida o un cambio urgente la organización puede identificar rápidamente al equipo responsable, el modelo está funcionando. Si todavía hacen falta cadenas de mensajes para descubrir quién mantiene un repositorio, el ownership sigue siendo nominal.
Riesgos habituales al implantar ownership
El primer riesgo es convertir el proceso en una auditoría puntual. Es tentador lanzar una campaña, rellenar owners y cerrar el proyecto. Pero el ownership caduca si no se integra en el ciclo de vida del repositorio. Nuevos repositorios, reorganizaciones, cambios de producto y migraciones pueden volver a generar ambigüedad en pocos meses.
El segundo riesgo es asignar ownership a equipos demasiado genéricos. Si todo pertenece a “Engineering” o “Platform”, el modelo no ayuda a enrutar decisiones. El owner debe estar lo bastante cerca del contexto como para actuar, pero lo bastante estable como para sobrevivir a cambios individuales.
El tercer riesgo es no archivar por miedo. Mantener repositorios abandonados “por si acaso” tiene coste: ruido, superficie de ataque y confusión. Un proceso de archivado con trazabilidad y ventana de objeción reduce ese miedo y convierte la limpieza en una práctica normal de ingeniería.
El cuarto riesgo es separar ownership de permisos. Un equipo puede figurar como owner sin tener capacidad real para revisar, modificar configuración o gestionar incidentes. Ownership sin permisos es responsabilidad sin autoridad. Permisos sin ownership es autoridad sin responsabilidad. El modelo necesita ambas cosas alineadas.
El quinto riesgo es confundir CODEOWNERS con ownership completo. CODEOWNERS ayuda a enrutar revisiones de código, pero no sustituye la responsabilidad operativa sobre el ciclo de vida del repositorio, sus dependencias, su seguridad, sus despliegues y su eventual archivado.
Checklist de implantación
Una checklist mínima para empezar podría ser:
- Inventario completo de repositorios de la organización.
- Identificación de repositorios archivados y activos.
- Señales de actividad y uso recopiladas.
- Clasificación inicial: activo, candidato a archivo o incierto.
- Owner sugerido para cada repositorio activo.
- Validación humana por equipos.
- Registro de owner duradero por repositorio.
CODEOWNERSrevisado donde aporte valor.- Reglas de protección de ramas aplicadas en repositorios críticos.
- Proceso de archivado con ventana de revisión.
- Métricas recurrentes de repositorios sin owner.
- Control para que repositorios nuevos nazcan con owner.
Fuentes recomendadas
- How GitHub gave every repository a durable owner — GitHub Blog.
- Acerca de los propietarios de código — GitHub Docs.
- Maintaining ownership continuity for your organization — GitHub Docs.
Conclusión
El caso de GitHub demuestra que el ownership de repositorios no es una tarea cosmética. Es una pieza estructural para operar software a escala.
Tener un owner duradero por repositorio permite reducir ambigüedad, mejorar la respuesta ante vulnerabilidades, archivar activos abandonados y construir controles DevSecOps sobre una base fiable.
Para organizaciones que trabajan con Azure, GitHub y plataformas de IA, la recomendación es clara: tratar el ownership como parte del diseño operativo, no como documentación opcional. Cada repositorio activo debería tener un equipo responsable, señales de ciclo de vida, reglas de revisión y un camino claro para archivarse cuando deje de aportar valor.
La automatización ayuda a descubrir, clasificar y vigilar. Pero la validación sigue siendo humana. Un owner duradero no es el resultado de un script; es un compromiso explícito de un equipo que acepta mantener, proteger y evolucionar un activo de software. Esa es la diferencia entre tener muchos repositorios y tener una plataforma de ingeniería gobernable.