GitHub навёл порядок во владении репозиториями

GitHub провела крупную кампанию по упорядочиванию внутренних репозиториев и ввела строгую модель владения ими. По данным компании, в начале 2025 года во внутренней организации GitHub было более 14 000 репозиториев, из них свыше 11 000 активных и при этом без явного владельца.

Для репозиториев, связанных с продакшен‑сервисами, давно существовала устойчивая модель ответственности через внутренний Service Catalog. Там фиксировались метаданные: с каким репозиторием связан сервис, какая команда и руководитель отвечают за него, а также данные для поддержки. Это позволяло запускать процессы, завязанные на сервисы, такие как реагирование на инциденты или управление уязвимостями.

Однако связь между сервисами и репозиториями была однонаправленной и ограниченной: один сервис мог ссылаться только на один репозиторий, а один репозиторий содержать несколько сервисов. Поэтому найти владельца по сервису было просто, а вот по репозиторию — только если он был привязан к сервису. Это оставляло «серую зону»: репозитории команд, документация, внутренние инструменты, одноразовые проекты и личные эксперименты.

Отсутствие явного владельца стало серьёзной проблемой во время масштабной кампании по устранению утечек секретов: технически секрет можно было отозвать, но без понятного владельца это создавало риск, срывы работы и неясные маршруты эскалации. По словам GitHub, слишком много времени уходило на поиск тех, кто отвечает за конкретный репозиторий.

Компания решила сделать владение репозиторием ключевым атрибутом и рассмотрела несколько вариантов хранения этой информации: отдельный файл в репозитории, централизованный репозиторий с данными, но в итоге выбрала пользовательские свойства (custom properties) GitHub. Такой подход дал структурированный, единый и доступный для запросов по всей организации способ управления владением и позволил привязывать политики и правила к типам владельцев.

GitHub создала два пользовательских свойства: ownership-type и ownership-name. Перед тем как просить команды что‑то заполнять вручную, инженеры настроили периодическую синхронизацию Service Catalog с пользовательскими свойствами репозиториев. Все репозитории, поддерживающие известные сервисы, автоматически получили тип владельца «Service Catalog» и заполненное имя владельца. Это покрыло около 1500 репозиториев; основная масса — репозитории команд, документации, одноразовые и личные проекты — осталась без владельцев.

Для внедрения проверки GitHub разработала GitHub App, работающий как задача CronJob в Kubernetes. Ему требовался доступ к Service Catalog, GitHub API и внутренним системам, поэтому обычного workflow в GitHub Actions было недостаточно. Приложение сканировало репозитории, проверяло наличие пользовательских свойств владения и применяло правила: создание issues‑предупреждений, автоматическое закрытие при исправлении или архивацию по истечении дедлайна.

Первый запуск CronJob назначили на утро субботы, рассчитывая на низкую активность сотрудников, но issues начали массово появляться во внутренних репозиториях, и обсуждение сразу ушло в Slack. Опыт показал, что в распределённой компании кто‑то всегда онлайн, и подобные изменения сразу вызывают реакцию.

После 30‑дневного льготного периода все репозитории без заполненных данных о владельце были заархивированы. GitHub выбрала именно архивацию, так как это обратимая и неразрушительная операция: репозиторий становится доступен только для чтения, GitHub Actions прекращает работу, но данные не удаляются. Если репозиторий снова нужен, его можно разархивировать, задать владельца и продолжить работу. Такой подход позволил распространять архивацию широко, не разбирая каждый частный случай.

После завершения начальной фазы компания сократила окно проверки с 30 дней до одного часа. Если новый репозиторий обходил требование о задании владельца при создании, система почти сразу помечала его как проблемный.

Роллаут прошёл в целом спокойно, однако вскрыл два интересных инцидента. В первом случае был заархивирован репозиторий без установленного владельца, куда Datadog автоматически создавал issues в рамках мониторинга. Архивация заблокировала создание issues, внутренний сервис мониторинга это обнаружил и направил оповещение команде‑владельцу, которая эскалировала ситуацию.

Этот случай выявил недочёт в уведомлениях: issues о владении создавались, но конкретные люди не получали прямых уведомлений. Для решения проблемы GitHub стала автоматически упоминать администраторов репозитория и назначать всех пользователей с правами записи ответственными по этим задачам. Так инженеры, способные указать владельца, гарантированно видят уведомление.

Второй инцидент был связан с качеством данных. Система была устойчива к полной недоступности Service Catalog, но не учитывала риск устаревших или повреждённых данных. Если бы Service Catalog ошибочно «забыл» записи о ряде сервисов, приложение могло бы решить, что их репозитории больше не связаны с сервисами, и массово отправить их в архив.

Чтобы снизить этот риск, GitHub ввела порог безопасности. Перед выполнением действий приложение подсчитывает, сколько репозиториев оно собирается архивировать и для скольких открыть issues. Если число превышает строго заданный порог, запуск прерывается, а в Datadog срабатывает мониторинг. Если Service Catalog недоступен, проверка ограничивается тем, что можно верифицировать независимо.

В итоге GitHub вышла на порядка 3000 активных репозиториев и около 11 000 архивированных (против примерно 3000 в архиве в начале проекта). Вся работа заняла менее 45 дней с первого запуска до стабильного состояния. Для каждого активного репозитория теперь либо подтверждён владелец, либо он автоматически переходит в архив.

Большая часть новых архивов — репозитории без коммитов на протяжении многих лет: заброшенные эксперименты, старые проекты хакатонов и одиночные прототипы вплоть до 2008 года. По оценке GitHub, их архивирование сократило потенциальную поверхность атак и сделало инвентарь действительно используемых репозиториев более точным.

Чтобы сохранить стопроцентное покрытие, компания внедрила обязательные свойства владения во все сценарии создания репозиториев, включая стандартную страницу создания и внутренние инструменты. Для новых репозиториев эти свойства стали обязательным полем, а потеря информации о владельце теперь обнаруживается в течение часа.

GitHub отдельно продумала модели устойчивости для разных типов владельцев. Записи в Service Catalog живут столько же, сколько сервис: при выводе сервиса из эксплуатации его репозитории чаще всего также архивируются, что совпадает с целевым поведением. Команды проходят проверку на наличие хотя бы одного участника, а структура команд обычно стабильна. Личные учётные записи сотрудников теряют актуальность при уходе человека из компании, и в этом случае их персональные репозитории логично отправить в архив. Для репозиториев, которые должны пережить конкретного человека, владельцем должна выступать команда или сервис, а не сотрудник.

GitHub отмечает, что подобную модель владения можно внедрить и в других организациях на основе пользовательских свойств GitHub. Рекомендуемый подход включает назначение свойств владения, автоматическую синхронизацию с каталогом сервисов, жёсткое требование указания владельца при создании репозитория и автоматическую архивацию репозиториев без валидных данных.

Автором инициативы выступил Michael Recachinas, Staff Security Engineer в GitHub. Он руководит масштабными программами в сфере безопасности, включая управление уязвимостями, инструменты безопасного жизненного цикла разработки и автоматизацию, ориентированную на разработчиков.

Источник: внутренний блог GitHub.

Читать новости ИИ и технологий в Telegram.


Оцените статью
Gimal-Ai