Сборка и подписание десктоп-приложения для macOS
Ситуация: приложение собрано, но на современных версиях macOS (14+) Gatekeeper блокирует запуск. Пользователи сообщают: «не может быть открыт, так как Apple не может проверить его». Корень — отсутствие подписи кода и нотаризации. Без них Gatekeeper блокирует запуск, а обход через «Системные настройки» требует нестандартных действий, которые большинство пользователей не выполнят.
Решить это можно за 3–4 дня, если правильно настроить цепочку: сертификат Developer ID → entitlements → подпись → нотаризация → stapling. Мы делаем это под ключ для Electron, Qt, SwiftUI и других фреймворков. За 5+ лет опыта мы провели более 50 релизов для macOS — ни один не был заблокирован. Apple Notarization Guide
Плата за вход: сертификат Developer ID Application можно получить только при наличии подписки Apple Developer Program (стоимость $99/год). Сама нотаризация для разработчиков бесплатна.
Почему подпись кода критична?
Подпись кода — это цифровая подпись разработчика, гарантирующая целостность приложения. macOS проверяет её при каждом запуске. Без неё Gatekeeper блокирует приложение, пользователь вынужден вручную разрешать запуск через «Системные настройки» или терминал. Для корпоративных сред это неприемлемо: MDM-политики запрещают запуск неподписанных приложений. Нотаризация добавляет проверку Apple на вредоносный код. Обе процедуры обязательны для распространения вне Mac App Store.
Как подписать и нотаризовать приложение для macOS?
Процесс включает 2 обязательных этапа: Code Signing и Notarization. Сначала получаете сертификат Developer ID Application (требуется Apple Developer Account). Затем конфигурируете сборку с правильными entitlements. Ниже — минимальный конфиг для Electron.
// electron-builder.yml
mac:
target:
- target: dmg
- target: zip
icon: build/icon.icns
category: public.app-category.productivity
hardenedRuntime: true
gatekeeperAssess: false
entitlements: build/entitlements.mac.plist
entitlementsInherit: build/entitlements.mac.plist
identity: "Developer ID Application: Company Name (TEAM_ID)"
<!-- build/entitlements.mac.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key><true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
<key>com.apple.security.network.client</key><true/>
</dict>
</plist>
Какие entitlements нужны для Electron-приложений?
Electron требует 4 ключа: allow-jit (для V8), allow-unsigned-executable-memory (для JIT-компиляции), allow-dyld-environment-variables (для Node.js) и network.client (для HTTP-запросов). Без них приложение вылетит при старте или не сможет выполнять сетевые запросы. Сравните с entitlements для нативных SwiftUI-приложений: там обычно достаточно com.apple.security.app-sandbox и com.apple.security.files.user-selected.read-write.
| Entitlement | Electron | SwiftUI | Qt |
|---|---|---|---|
| com.apple.security.cs.allow-jit | Да | Нет | Да |
| com.apple.security.cs.allow-unsigned-executable-memory | Да | Нет | Да |
| com.apple.security.cs.allow-dyld-environment-variables | Да | Нет | Да |
| com.apple.security.network.client | Да | Да | Да |
| com.apple.security.app-sandbox | Опционально | Да | Опционально |
Нотаризация и stapling
После подписи отправляем .dmg на нотаризацию через notarytool. Apple сканирует бинарники на вирусы и вредоносный код. Результат — нотаризационный тикет, который встраивается в файл командой stapler.
# Через notarytool (Xcode 13+)
xcrun notarytool submit AppName.dmg \
--apple-id "[email protected]" \
--password "@keychain:AC_PASSWORD" \
--team-id "TEAM_ID" \
--wait
# Stapling (встраивание нотаризационного тикета в файл)
xcrun stapler staple AppName.dmg
Notarytool работает в 3 раза быстрее старого altool и имеет лучший уровень поддержки, так как активно развивается Apple.
Пошаговая настройка подписи в CI/CD
- Получите сертификат Developer ID Application в Apple Developer Portal (сертификат типа Developer ID Application, не Development).
- Экспортируйте сертификат в .p12 и сохраните в секретах CI (например, GitHub Secrets).
- Настройте
electron-builderили аналог с нужными entitlements (см. выше). - Добавьте шаг импорта сертификата в CI-пайплайн.
- Настройте этап нотаризации с
notarytoolи stapling. - Протестируйте сборку на локальной машине и в CI.
GitHub Actions для macOS
- uses: actions/checkout@v3
- name: Import Certificate
run: |
echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12
security import certificate.p12 -P "$MACOS_CERTIFICATE_PWD" \
-A -t cert -f pkcs12 -k ~/Library/Keychains/login.keychain
- name: Build and Sign
run: npm run build:mac
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
CSC_LINK: ${{ secrets.MACOS_CERTIFICATE }}
CSC_KEY_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
Universal Binary (Intel + Apple Silicon)
Universal binary — это сборка, содержащая обе архитектуры (x86_64 и arm64). Она работает нативно на M1/M2/M3 без Rosetta 2. Это обязательное требование для App Store и многих корпоративных сред. Экономия производительности: без universal binary вы теряете до 30% на Apple Silicon.
# electron-builder автоматически создаёт universal binary
npx electron-builder --mac --universal
Что входит в настройку под ключ
| Этап | Длительность | Результат |
|---|---|---|
| Анализ проекта | 1 день | Список необходимых entitlements, сертификатов, инфраструктура CI |
| Настройка сборки и подписи | 1–2 дня | Рабочий CI-пайплайн с подписью кода |
| Нотаризация и тестирование | 1 день | Нотаризованный .dmg, stapled |
| Документация и обучение | 0.5 дня | README, описание процесса, инструкция для команды |
Дополнительно: настройка автоматического обновления (Sparkle, Electron auto-updater), white-label подпись, работа с Apple Developer Enterprise Program.
Типичные ошибки
- Использование сертификата Apple Development вместо Developer ID — подпись только для отладки.
- Пропуск
hardenedRuntime: true— нотаризация не пройдёт. - Неправильные entitlements для Electron — падение при старте.
- Отсутствие stapling — пользователи увидят предупреждение, если нет интернета.
- Забыли про universal binary — потеря производительности на Apple Silicon.
- Сертификат Developer ID Application не подходит, если вы ошиблись типом (нужен именно Developer ID, а не Development).
- Нотаризация не проходит, если не включён
hardenedRuntime. - Приложение падает при старте — проверьте entitlements: для Electron обязательны
allow-jitиallow-unsigned-executable-memory. - Stapling не срабатывает, если файл повреждён — выполните
staplerсразу послеnotarytool.
Опираясь на наш опыт, мы рекомендуем тестировать нотаризацию на каждом релизе. Даже замена версии Electron может сломать entitlements.
Сроки и гарантия
Базовая настройка занимает 3–4 рабочих дня. Мы гарантируем, что приложение пройдёт нотаризацию и будет запускаться на macOS 10.14 и новее. Свяжитесь с нами, чтобы настроить подпись за 3-4 дня и избежать блокировок Gatekeeper. Получите консультацию по вашему проекту — мы поможем избежать типичных ошибок и сэкономить время.







