2026-04-22 iOS Keychain и гигиена профилей для CI на безголовом арендованном облачном Mac
Релиз-менеджеры и владельцы iOS CI, арендующие Apple Silicon Mac по SSH, упираются в одну стену: локально Archive успешен, а на удалённом билдере та же ветка падает с errSecInternalComponent, «нет сертификата подписи» или устаревшими UUID профилей. Этот материал от 2026-04-22 объясняет, как выровнять login keychain, профили провижининга и идентичности codesign для безлюдных заданий в HK / JP / KR / SG / US. Вы получите две сравнительные таблицы, усиленный SSH‑процесс, числовой бюджет NVMe и ссылки на авто vs ручная подпись, экспорт и API ASC, параллельный xcodebuild.
Поверхность сбоев на безголовых билдерах
В отличие от ноутбука с UI, арендованный облачный Mac часто запускает xcodebuild из неинтерактивной оболочки. Типичные разрывы раскладываются на три слоя: состояние связки ключей, свежесть профиля, несовпадение идентичности.
| Симптом | Типичная причина | Первая диагностика |
|---|---|---|
errSecInternalComponent при codesign |
Заблокированная login keychain или запрет на приватный ключ | security list-keychains + аудит unlock для CI‑пользователя |
| Профиль «не включает сертификат подписи» | UUID на диске ≠ профиль, встроенный в target | Сравнить ~/Library/MobileDevice/Provisioning Profiles с отчётом Xcode |
| На ветке A ок, на B нет | Несколько идентичностей с одним CN; выбрана неверная | security find-identity -v -p codesigning + явный CODE_SIGN_IDENTITY |
xcodebuild archive, когда копятся символы и срезы — см. хранение dSYM.
Режимы подписи: матрица решений
Прежде чем трогать keychain, решите, опирается ли билдер на автоподпись с управляемыми профилями Xcode или на ручную подпись с закоммиченными профилями. Ответ зависит от частоты ротации сертификатов и совместного использования хоста.
| Режим | Лучше всего когда | Операционные затраты | Риск на Mac только с SSH |
|---|---|---|---|
| Авто + управление Xcode | Быстрые итерации, мало bundle ID | Ниже уход за профилями | Средний — зависит от здоровья сессии Apple ID |
| Ручной + закоммиченные профили | Enterprise‑конвейеры, воспроизводимые архивы | Выше дисциплина ротации | Ниже — явные UUID и идентичности |
| Эфемерная связка на задание | Мультитенантные хосты | Максимум автоматизации | Минимум утечек между командами при правильной реализации |
Дисциплина keychain для SSH‑сессий
CI‑пользователи на облачных Mac должны относиться к login.keychain-db как к живой БД: только один автоматизированный субъект импортирует, шаги разблокировки явные.
- Префлайт — список связок и default.
- Unlock — одобренная неинтерактивная разблокировка (пароль из секрет‑хранилища, не plaintext в репо).
- Разделение списков —
codesignиproductbuildполучают доступ к ключу без лишнего расширения ACL. - После задания — удалить временные сертификаты и слегка «пропылесосить» сироты.
security unlock-keychain -p "$KEYCHAIN_PASSWORD" ~/Library/Keychains/login.keychain-db
Жизненный цикл профилей провижининга
Профили на диске должны отражать то, что Xcode разрешает при архивации. Инварианты:
- Имя файла = UUID профиля
<UUID>.mobileprovision— переименование маркетинга ломает автоматизацию тихо. - Алерты по сроку T-30, T-14, T-7 для App Store distribution; API ASC могут питать опросы.
- После обновления удаляйте устаревшие UUID, чтобы Xcode не выбрал «почти верный» профиль.
Сочетайте раздел с опциями экспорта и API ASC, чтобы загрузка не шла с зелёным архивом, но с просроченным distribution‑профилем в кэше.
Идентичности, embedded.mobileprovision и экспорт
Сперва security find-identity -v -p codesigning, затем явно зафиксируйте CODE_SIGN_IDENTITY в CI‑матрицах. При экспорте IPA убедитесь, что встроенный профиль соответствует каналу (TestFlight vs Ad Hoc). Если есть символикация крэшей, свяжите гигиену подписи с dSYM, чтобы UUID совпадали end‑to‑end.
Схема секретов и бюджет NVMe
Мультипроектные команды в Сингапуре и на востоке США часто планируют пересекающиеся архивы. Разделяйте:
- Корни подписи — отдельные каталоги команд под контролируемым префиксом вроде
/var/lib/ci. - DerivedData — временные корни на задание, как в статье об изоляции.
- Ретеншн артефактов — три последних дерева
.xcarchiveдля отката, старые срезы подчищать.
При распараллеливании следуйте параллельному xcodebuild, чтобы давление CPU не усиливало ретраи подписи, маскируя ошибки keychain.
Связанные гайды на MacXCode
Стратегия — авто vs ручная подпись, основы аккаунта — справка, отдельные хосты подписи по регионам — цены.
FAQ: keychain и профили
| Вопрос | Практический ответ |
|---|---|
| Делить один Apple ID между CI‑пользователями? | Избегайте — сегментируйте сервисные аккаунты по семействам приложений и аудируйте логины ежеквартально. |
| Нужен ли VNC? | Только для первичных доверительных промптов; в штате — SSH + логи. См. гайд по VNC. |
| Самый быстрый откат при поломке подписи? | Восстановить вчерашний набор профилей из VCS и реимпортировать идентичности из офлайн‑бэкапа — затем один rebuild, а не пять вслепую. |
Почему Mac mini M4 на bare metal всё ещё выигрывает в пропускной способности подписи
Узлы Mac mini M4 на Apple Silicon дают предсказуемую задержку codesign, потому что крипто и I/O идут на локальный NVMe без гипервизора, ворующего бюджет прерываний — критично при цепочке архив → экспорт → загрузка под SLA. Присутствие MacXCode в HK / JP / KR / SG / US позволяет держать хосты подписи рядом с тестировщиками при едином SSH‑потоке, опциях 1–2 ТБ и bare‑metal‑изоляции без «шумных соседей» в перегруженных ВМ. Больше приложений, чем ключей — добавляйте билдеры через цены, а не перегружайте одну связку.