Как подписать приложение macOS: пошаговое руководство

Подписать приложение macOS можно напрямую из терминала командой codesign — для этого достаточно действующего сертификата разработчика Apple и нескольких минут времени. Однако если сертификат отсутствует, истёк или выбран не того типа, Gatekeeper заблокирует запуск программы на чужом Mac с предупреждением о неустановленном разработчике.

В этой статье разберём полный цикл: от получения сертификата до проверки подписи и нотаризации. Материал пригодится как тем, кто распространяет приложение через Mac App Store, так и разработчикам, публикующим сборки напрямую со своего сайта.

Зачем вообще подписывать приложение

Подпись кода — это криптографическое подтверждение того, что приложение создано конкретным разработчиком и не изменялось после сборки. Без неё Gatekeeper в macOS относит программу к категории потенциально опасных: пользователь увидит диалог «Приложение не может быть открыто, так как не удалось проверить разработчика».

Подпись решает сразу несколько задач. Она удостоверяет личность разработчика, защищает целостность бинарных файлов и ресурсов, а также позволяет системе проверять версии при обновлении. Для распространения вне Mac App Store дополнительно требуется нотаризация — автоматизированная проверка приложения на серверах Apple.

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

Типы сертификатов и где их получить

Сертификаты выдаются через учётную запись разработчика Apple. Для личных экспериментов достаточно бесплатного Apple ID, но такой сертификат ограничен локальным запуском. Для распространения приложений другим пользователям потребуется платная программа Apple Developer Program.

Основные типы сертификатов, которые встречаются при работе с macOS:

  • 🔑 Apple Development — для разработки и запуска на собственных устройствах;
  • 📦 Apple Distribution — для публикации в Mac App Store;
  • 🌐 Developer ID Application — для распространения приложений вне магазина;
  • 🛠 Developer ID Installer — для подписи установочных пакетов .pkg.

Создать сертификат можно в разделе Certificates, Identifiers & Profiles на портале разработчика Apple или прямо из Xcode через Settings → Accounts → Manage Certificates. После выпуска сертификат автоматически попадает в связку ключей Keychain Access вместе с закрытым ключом.

⚠️ Внимание: закрытый ключ существует только на том Mac, где был сгенерирован запрос на сертификат. Если переустановить систему без резервной копии связки ключей, сертификат станет бесполезным — экспортируйте пару «сертификат + ключ» в файл .p12 и храните отдельно.

Подписание через Xcode

Самый простой путь — доверить подпись среде разработки. В настройках проекта откройте вкладку Signing & Capabilities, включите опцию Automatically manage signing и выберите свою команду (Team). Xcode сам запросит нужный сертификат, создаст профили и подпишет сборку.

Для ручного контроля отключите автоматическое управление и укажите конкретный сертификат и профиль обеспечения (provisioning profile). Это удобно в командной разработке, когда сборки проходят на CI-сервере и нужна предсказуемость.

Обратите внимание на секцию Hardened Runtime — усиленная среда выполнения обязательна для нотаризации. Включите её там же, на вкладке подписи, и добавьте только те исключения (entitlements), которые действительно нужны приложению.

📊 Как вы чаще всего подписываете приложения macOS?
Автоматически через Xcode
Вручную через codesign
Через CI/CD-скрипты
Пока только изучаю тему

Ручное подписание командой codesign

Когда сборка происходит без Xcode — например, приложение на Electron, Qt или собранное сторонними инструментами — используется утилита codesign. Базовая команда выглядит так:

codesign --force --deep --sign "Developer ID Application: Имя (TEAMID)" MyApp.app

Ключ --force перезаписывает существующую подпись, --deep подписывает вложенные библиотеки и фреймворки. Однако флаг --deep считается устаревшим подходом: надёжнее подписывать вложенные компоненты по отдельности, двигаясь изнутри наружу — сначала библиотеки и хелперы, затем само приложение.

Для нотаризации добавьте флаг усиленной среды выполнения и временную метку:

codesign --sign "Developer ID Application: Имя (TEAMID)" --options runtime --timestamp MyApp.app

Порядок имеет значение. Типичная последовательность выглядит так:

  • 📚 подпишите все .dylib и фреймворки внутри бандла;
  • 🧩 подпишите вспомогательные исполняемые файлы и плагины;
  • 📱 подпишите основной бандл .app с флагом --options runtime;
  • ✅ проверьте результат командой верификации.

☑️ Проверка перед подписанием

Выполнено: 0 / 5

Проверка подписи

После подписания обязательно убедитесь, что всё прошло корректно. Базовая проверка выполняется той же утилитой:

codesign --verify --deep --strict --verbose=2 MyApp.app

Если команда завершилась без ошибок, подпись валидна. Посмотреть детали — кем подписано, какие права (entitlements) выданы — можно так:

codesign -dvvv MyApp.app

Дополнительно проверьте, как приложение оценит Gatekeeper:

spctl --assess --type execute --verbose MyApp.app

Ответ accepted с указанием источника Developer ID означает, что система пропустит запуск. Ответ rejected — повод перепроверить сертификат и нотаризацию.

Нотаризация приложения

Подписи Developer ID недостаточно: начиная с современных версий macOS, приложения, распространяемые вне App Store, должны пройти нотаризацию. Это автоматическая проверка на серверах Apple, после которой к приложению прикрепляется «билет» (ticket).

Отправка на проверку выполняется утилитой notarytool. Приложение сначала упаковывается в .zip или .dmg, затем загружается командой:

xcrun notarytool submit MyApp.zip --apple-id "ваш@email" --team-id "TEAMID" --password "пароль_приложения" --wait

Здесь используется не обычный пароль от Apple ID, а специальный пароль приложения, который генерируется в настройках учётной записи Apple ID. После успешной проверки прикрепите билет к файлу:

xcrun stapler staple MyApp.app
⚠️ Внимание: нотаризация отклонит приложение, если не включён Hardened Runtime, отсутствует защищённая временная метка или внутри бандла остались неподписанные компоненты. Лог отказа можно запросить командой xcrun notarytool log с идентификатором отправки.

Типичные ошибки и их решения

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

ОшибкаВозможная причинаЧто проверить
certificate expiredИстёк срок действия сертификатаОбновить сертификат на портале разработчика
no identity foundСертификат не установлен в KeychainИмпортировать .p12 вместе с закрытым ключом
code object is not signed at allНеподписанный вложенный компонентПодписать библиотеки до подписи бандла
resource fork / Finder informationРасширенные атрибуты файлов ломают подписьОчистить атрибуты: xattr -cr MyApp.app
the executable does not have the hardened runtime enabledНе включён Hardened RuntimeПереподписать с --options runtime

Отдельного упоминания заслуживает ситуация, когда приложение подписано корректно, но на машине пользователя всё равно не запускается. Частая причина — отсутствие нотаризации или повреждение бандла при передаче через архиваторы и файлообменники, которые добавляют свои метаданные. Передавайте приложение только в подписанном DMG-образе или ZIP-архиве, созданном стандартными средствами macOS — это сохраняет подпись нетронутой.

Как подписать DMG-образ

DMG подписывается отдельно той же командой codesign: codesign --sign "Developer ID Application: Имя (TEAMID)" MyApp.dmg. Нотаризуется именно DMG, а билет прикрепляется к нему через xcrun stapler staple MyApp.dmg.

Ad-hoc подпись для локального использования

Если приложение нужно только вам — например, собранная из исходников утилита — не обязательно оформлять сертификат. Достаточно ad-hoc подписи, которая не привязана ни к какой учётной записи:

codesign --force --sign - MyApp.app

Такая подпись не пройдёт проверку Gatekeeper на других компьютерах, но позволит системе корректно работать с приложением локально: выдавать разрешения на доступ к камере, файлам и другим ресурсам. На Mac с Apple Silicon ad-hoc подпись вообще обязательна — неподписанный исполняемый код на этих машинах не запускается.

Часто задаваемые вопросы

Можно ли подписать приложение без платного аккаунта Apple Developer?

Да, но с ограничениями. Бесплатная учётная запись позволяет подписывать приложения для запуска на собственных устройствах. Для распространения другим пользователям вне App Store потребуется платная программа разработчика с сертификатом Developer ID.

Чем подпись отличается от нотаризации?

Подпись выполняется локально и подтверждает авторство и целостность кода. Нотаризация — это отправка приложения на серверы Apple для автоматической проверки, после которой выдаётся билет, позволяющий Gatekeeper беспрепятственно запускать программу.

Что делать, если Keychain не видит сертификат?

Проверьте, что импортирован не только сертификат, но и закрытый ключ — они должны отображаться в связке ключей как связанная пара. Если ключ утерян, сертификат придётся отозвать и выпустить заново на портале разработчика.

Нужно ли переподписывать приложение после каждого изменения?

Да. Любая модификация файлов внутри подписанного бандла делает подпись недействительной. После правок кода, ресурсов или библиотек приложение подписывается заново, а для распространения — повторно отправляется на нотаризацию.

Как проверить, подписано ли чужое приложение?

Выполните в терминале команду codesign -dv /Applications/ИмяПриложения.app — она покажет автора подписи и тип сертификата. Дополнительно spctl --assess покажет, как приложение оценивает Gatekeeper.