Руководство для сопровождающих проектов, команд iOS и инженеров платформы, которым нужно решить, можно ли запускать внешние PR на собственных Mac Runner. Разбираем границы доверия, доступ репозиториев, секреты, остаточное состояние узла и порядок восстановления; в конце — условия допуска или блокировки задания.
Внешний PR прошёл сборку на вашем Mac Runner, но рабочий каталог, процессы и доступ к подписи остались на узле.
Быстрое решение: не запускайте недоверенный workflow на постоянном Mac Runner, который хранит секреты или состояние предыдущих заданий. Разделите внешние PR и доверенные публикации, ограничьте доступ репозиториев и групп Runner, а очистку проверяйте реальным тестовым запуском.
Подходит сопровождающим открытых проектов, которым нужно решить, куда направлять вклад от внешнего участника. Подходит специалистам по безопасности iOS-сборок, разделяющим тестирование и подпись релизов. Подходит инженерам платформы, отвечающим за группы Runner, доступ репозиториев и восстановление узлов.
Почему источник workflow важнее метки Runner
При проверке внешнего PR выполняется не только код приложения. Workflow задаёт исполняемые команды, шаги и используемые действия. Поэтому решение о запуске должно начинаться с вопроса: кто контролирует изменения, которые будут выполнены на узле?
Мы разделяем события на три категории:
- Доверенная ветка. Изменения внесены участниками, которым разрешено менять workflow и использовать предусмотренные полномочия.
- Внутренний PR. Автор работает внутри организации, но это не делает каждое изменение автоматически безопасным. Проверяйте права автора и правила ревью.
- PR внешнего участника. Код и изменения workflow приходят из недоверенного источника. Считайте исполняемое задание потенциально вредоносным, пока не доказано обратное.
GitHub предупреждает, что self-hosted runner может быть скомпрометирован кодом, выполняемым в задании, а последствия могут затронуть среду и другие данные, доступные узлу. Это принципиальная разница с одноразовым размещённым исполнителем: собственный Mac может сохранять состояние между задачами. Сверяйте свою модель угроз с официальной документацией GitHub о безопасном использовании Actions и self-hosted runners.
Триггер тоже имеет значение. Сопоставьте фактическое событие запуска с тем, какие данные и полномочия доступны workflow: справочник GitHub по событиям, запускающим workflow. Не считайте имя ветки или наличие ручного подтверждения заменой анализа происхождения кода.
Отдельно проверьте pull_request_target. Такой workflow выполняется в контексте базового репозитория, поэтому не следует бездумно соединять его привилегированный контекст с кодом из PR. GitHub описывает этот риск и безопасное использование события в специальном руководстве по pull_request_target. Если workflow получает содержимое PR и запускает его, оцените весь путь данных: событие, checkout, команды сборки и доступные ему полномочия.
Доступ к узлу: кто может направить туда задание
Самостоятельный Runner не становится изолированным только потому, что в workflow указан ожидаемый label. Label помогает выбрать исполнитель, но не является самостоятельным механизмом авторизации. Если репозиторий или workflow имеет доступ к группе, совпадение метки не доказывает, что доступ ограничен правильно.
Проверьте настройки группы Runner на уровне организации: какие репозитории включены, как задаются разрешения и кто может менять этот список. В документации GitHub по управлению доступом к self-hosted runners и по группам Runner описаны соответствующие модели доступа. Сверяйте фактическую политику группы с перечнем репозиториев, а не только названия групп в YAML.
Мы используем такой разбор «пройдено / не пройдено»:
- Пройдено: для группы указан ожидаемый круг репозиториев; незнакомые репозитории не могут направлять туда workflow; изменение политики требует контролируемого доступа.
- Не пройдено: разрешение выдано шире необходимого, список не проверяется или администраторы не могут объяснить, почему конкретный репозиторий допущен.
- Пройдено: доступ к runner-группе проверен с точки зрения настроек организации и конкретных workflow.
- Не пройдено: команда считает правильный label достаточным ограничением.
Если пройти проверку доступа нельзя, не отправляйте туда внешний PR. Для общей ориентировки по доступным вариантам удалённой Mac-среды можно посмотреть страницу аренды облачного Mac, но конкретные границы доступа всё равно нужно подтвердить по фактической конфигурации выбранной среды.
Секреты и подпись должны быть вне тестового пути
Тестовая сборка может не показывать ключ подписи в журнале и всё же иметь возможность использовать доступные ей полномочия. Поэтому проверяйте не видимость секрета в выводе, а то, может ли workflow получить секрет, передать его команде или выполнить действие от имени релизной инфраструктуры.
GitHub описывает правила использования секретов и ситуации, в которых workflow может к ним обращаться, в документации по secrets. Используйте её, чтобы проверить настройку репозитория, контекст события и конкретные шаги задания. Не предполагайте, что секрет защищён лишь потому, что его значение скрыто интерфейсом или маскируется в логах.
Рабочая схема разделяет задачи по назначению:
- Проверка внешнего PR: сборка и тесты с минимальными полномочиями; ключи подписи, токены публикации и доступ к релизным ресурсам не предоставляются.
- Релизная сборка: отдельный доверенный workflow, запускаемый при соблюдении правил проекта; необходимые ему секреты не должны автоматически попадать в контекст внешней проверки.
- Подтверждение: проверяющий фиксирует, какое событие запустило задачу и какие именно полномочия были ей доступны.
Если тесту нужен доступ к закрытому ресурсу, это не повод незаметно передавать ему релизный секрет. Сначала выясните, можно ли исключить секрет из тестового пути, использовать безопасные тестовые данные или изменить сам способ проверки. Пока назначение и границы секрета не ясны, результат — не пройдено.
Для iOS-команды важна не только сама подпись. Проверьте доступ workflow к материалам, которыми можно подписывать или публиковать сборку, а также к конфигурации, позволяющей их использовать. Проверка должна охватывать все шаги, включая скрипты сборки и действия, выполняемые до или после компиляции.
Остаточное состояние: очистку нужно доказать
На долгоживущем Mac Runner рабочая директория — не единственное место, где может остаться след задания. Проверьте кэш сборки, временные файлы, загруженные материалы и процессы, созданные командами workflow. Отдельно выясните, какие каталоги общие для разных задач и какой пользователь запускает команды. Это практические границы аудита; сама запись в YAML не доказывает чистоту узла.
GitHub документирует возможность выполнять скрипты до и после задания для self-hosted runners в руководстве по скриптам подготовки и очистки. Наличие такого механизма не означает, что конкретный узел очищается корректно: проверьте настройки, фактическое выполнение скрипта, ошибки и доступные журналы.
Проведите безопасную проверку на тестовом задании без реальных секретов:
- Создайте временный файл с безвредным маркером в рабочем каталоге и убедитесь после завершения, что его нет.
- Запустите контролируемую фоновую задачу, затем проверьте, что она остановлена, а не продолжает работать после завершения workflow.
- Создайте тестовый объект в разрешённом временном каталоге и проверьте, что политика очистки его удаляет.
- Посмотрите логи подготовки и завершения задания. Ошибка очистки, пропущенный скрипт или непроверяемый результат означают, что узел пока нельзя считать чистым.
- Проверьте состояние самого Runner перед следующим заданием и зафиксируйте, кто отвечает за его возврат в пул.
Успешное завершение workflow не является доказательством успешной очистки. Если состояние узла нельзя проверить, безопаснее вывести его из маршрутизации и восстановить из доверенного образа или другого проверенного состояния.
Кэш заслуживает отдельного внимания: он может быть нужен сборкам, но может также переносить содержимое между задачами. Опишите, кто может записывать данные, какие задания могут их читать и как удаляются устаревшие данные. Если неизвестно, как внешний PR влияет на кэш, временно отключите совместное использование для недоверенного пути либо направьте его в другую среду.
Условия допуска и отказа для внешнего PR
Используйте список ниже как инструмент принятия решения, а не как декларацию соответствия. Проверка не заменяет анализ угроз проекта и не подтверждает соответствие какому-либо стандарту или сертификации.
Проверка перед допуском
Отметьте пункт только после проверки настройки или тестового запуска. Если хотя бы один пункт в критических областях доступа, секретов или очистки не пройден, внешний PR нельзя направлять на этот постоянный узел.
- [ ] Источник задания определён: внешний код рассматривается как недоверенный, а событие запуска и его контекст проверены.
- [ ] Доступ группы Runner ограничен ожидаемыми репозиториями; список разрешённых репозиториев проверен в настройках организации.
- [ ] Label используется только для маршрутизации, а не принимается за средство ограничения доступа.
- [ ] Тестовый workflow не получает ключи подписи, токены публикации и доступ к релизным ресурсам, если они не нужны для проверки.
- [ ] Рабочие файлы, временные данные и тестовый кэш удаляются после задания; результат подтверждён фактическим запуском.
- [ ] Контролируемый фоновый процесс завершён; после теста на узле не осталось неизвестных процессов.
- [ ] Ошибка очистки приводит к блокировке узла, а не к автоматическому возврату в общий пул.
- [ ] Назначены ответственные за проверку журналов, восстановление узла и повторный допуск.
Решение по чек-листу:
- Если все пункты пройдены, допускайте запуск только в пределах проверенной схемы и периодически повторяйте проверку после изменения workflow, прав или конфигурации Runner.
- Если не пройден пункт о происхождении кода, доступе репозиториев, секретах или очистке, блокируйте запуск внешнего PR на этом узле.
- Если проблема локальна и её можно устранить без расширения полномочий, сначала исправьте настройку, затем повторите тест. До повторной проверки направляйте задание в изолированную среду или оставляйте self-hosted runners только для доверенных workflow.
По нашей оценке готовности результат относится к одному из трёх состояний:
- Допуск: критические проверки подтверждены настройками и тестовым заданием.
- Условный допуск: остаётся пробел, не расширяющий полномочия внешнего PR; он зафиксирован, а ответственный и срок проверки определены.
- Блокировка: доступ слишком широк, чувствительные секреты доступны тесту или очистку нельзя подтвердить.
При блокировке не ограничивайтесь изменением workflow-файла. Уберите узел из доступной маршрутизации, проверьте его состояние, остановите оставшиеся процессы, сохраните нужные журналы и выполните восстановление из доверенного состояния. После этого перепроверьте настройки доступа и проведите тестовую задачу заново. Единичный успешный запуск показывает только, что проверка прошла в конкретных условиях; это не гарантирует безопасность будущих заданий.
Частые вопросы о внешних PR и Mac Runner
Можно ли запускать PR внешних участников на собственном Mac Runner?
Технически это возможно, но запускать недоверенный код на постоянном узле без изоляции не следует. Сначала проверьте, какие репозитории могут использовать Runner, какие полномочия получает workflow и что остаётся после задания. Если нельзя исключить доступ к секретам, рабочему каталогу или фоновым процессам, направляйте такой PR в изолированную среду либо блокируйте выполнение.
Как ограничить список репозиториев, которым доступен Mac Runner?
Проверьте политику группы Runner на уровне организации и укажите разрешённые репозитории согласно модели доступа проекта. Затем изучите маршрутизацию workflow: метка Runner выбирает подходящий узел, но сама по себе не запрещает другим репозиториям обратиться к нему. Сверьте фактические права с документацией GitHub по управлению доступом и проверьте их тестовым заданием.
Как отделить ключи подписи от тестирования внешних PR?
Не выдавайте тестовому workflow секреты подписи и публикации, если они не нужны для проверки. Разделите тестовые и релизные задания, а выдачу полномочий публикации привяжите к доверенному событию и отдельным правилам. Отсутствие секрета в журнале не доказывает, что код задания не мог его прочитать или передать другим способом; проверяйте доступ и контекст запуска.
Что проверить на Mac Runner после выполнения внешнего кода?
Проведите безопасное тестовое задание и убедитесь, что удалены рабочие файлы, временные данные и созданный кэш, а запущенные процессы завершены. Проверьте журналы и состояние узла, прежде чем возвращать его в пул. Если очистку нельзя подтвердить или остались неизвестные процессы и файлы, исключите узел из маршрутизации, восстановите его из доверенного состояния и назначьте ответственного за повторную проверку.
Когда собственный Mac перестаёт быть разумным местом для теста
Мы не рекомендуем считать постоянный Mac Runner универсальным решением для внешних PR: он может сохранять рабочее состояние, делить узел с задачами другого уровня доверия, а очистка требует отдельной проверки и ответственности. Если проекту нужна удалённая Mac-среда для контролируемых сборок, сравните варианты размещения и доступности, например облачный Mac в восточной части США, не принимая регион или аренду за автоматическую гарантию изоляции.
Сначала примените условия допуска к текущей конфигурации: проверьте доступ репозиториев, политику секретов и тест очистки. Если нужны временные или отделённые сборочные узлы, изучите доступные варианты аренды облачного Mac и отдельно подтвердите, какие права, очистка и восстановление предусмотрены выбранной конфигурацией. Для постоянной тяжёлой нагрузки с необходимостью физического интерфейса собственный выделенный Mac может быть подходящим выбором; для недоверенных PR ключевой критерий — подтверждаемая граница между заданием и остальными данными.
Выделите отдельный Mac для внешних PR
Запускайте проверки внешних PR на отдельном bare-metal Mac от ZekVPS, не совмещая их с доверенными сборками.
Полноценная macOS подходит для сборки приложений, работы с симулятором и задач CI/CD.
Чтобы перевести MCP или Agent из демо в ежедневную работу, сначала зафиксируйте облачный Mac со снимками. Смотреть тарифы ZekVPS Mac mini — Разделите лабораторию и рабочий стол — деплой станет спокойнее.