# Как проверить загруженное приложение для macOS до первого запуска

Приложение безопасности по своей задумке получает необычно широкий доступ. Оно может читать сетевой трафик, добавлять системное расширение, устанавливать привилегированный вспомогательный компонент, проверять файлы или запрашивать разрешения на запись экрана и универсальный доступ. Относиться к его первому запуску как к установке обычного приложения - ошибка, которой легко избежать.

Для грамотной проверки не нужно изучать весь продукт методом обратной разработки. Нужно убедиться, что вы получили нужный файл, что его издатель соответствует ожидаемому, что содержимое по-прежнему совпадает с подписанным выпуском и что macOS принимает его в рамках обычных механизмов защиты. Сделайте это до выдачи приложению разрешений, учётных данных или пароля администратора.

Эта проверка намеренно повторяется. В этом её сила. Одноразовый ритуал, основанный на случайном предупреждении macOS, легко обойти. Короткая запись одинаковых проверок для каждого нового приложения безопасности сложнее для обмана, а передать её другому инженеру проще.

## Имя файла не является издателем

Файл с именем `Acme Security.app` почти ничего вам не сообщает. Скопировать значок, знакомое название продукта и аккуратно оформленную страницу загрузки несложно. Нужно установить личность, записанную в подписи, а затем сравнить её с информацией, полученной от издателя по независимому каналу.

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

Здесь есть два разных вопроса:

- Пришёл ли этот файл из того места, которым я собирался пользоваться?
- Совпадает ли издатель, подписавший исполняемый файл, с тем издателем, которому я собирался доверять?

Эти вопросы часто объединяют. Так скомпрометированная страница загрузки поставщика может пройти поверхностную проверку, а приложение с действительным Apple Developer ID получает доверие лишь потому, что его название похоже на имя известного поставщика.

Сформируйте ожидания до проверки файла. Запишите название продукта, версию, ожидаемый тип файла, имя издателя и опубликованные Team Identifier или сведения о сертификате подписи. Если поставщик никогда не публиковал стабильный идентификатор, используйте несколько независимых сигналов: документацию, исходный репозиторий, уже проверенный прежний выпуск и ответ поддержки от известного контакта. Одной строки с именем субъекта сертификата недостаточно, если у вас нет прежних оснований связывать её с поставщиком.

От приложения, которое защищает другое ПО, я ожидаю прозрачности. Поставщик, который просит отключить Gatekeeper, выполнить curl pipe в shell или проигнорировать несоответствие без точного объяснения, уже провалил проверку установки.

## Проверьте полученный файл до открытия

Проверьте загруженный контейнер до переноса приложения в Applications или запуска установщика. Контейнер определяет, какие команды нужны и что произойдёт дальше.

`.dmg` - это образ диска. Его подключение открывает содержимое, но само по себе не должно запускать приложение. `.pkg` - установочный пакет, который после разрешения Installer может изменить систему. `.zip` - архив, обычно распаковывающийся в пакет приложения или другой контейнер. Отдельный `.app` уже является пакетом приложения.

Не изменяйте исходную загрузку до окончания проверки. Finder часто автоматически распаковывает ZIP-файлы. Это удобно, но из-за этого проще потерять точный файл, для которого поставщик опубликовал хеш. Если издатель указал SHA-256 для ZIP, проверьте ZIP до распаковки. Если контрольная сумма относится к образу диска, проверьте образ до подключения.

В Terminal используйте путь в кавычках. Если перетащить файл из Finder в Terminal, путь вставится безопасно.

```sh
shasum -a 256 "$HOME/Downloads/VendorSecurity.dmg"
```

Результат выглядит так:

```text
9fd1...e84c  /Users/you/Downloads/VendorSecurity.dmg
```

Сравните все 64 шестнадцатеричных символа со значением издателя. Не сверяйте первые несколько символов и не считайте проверку законченной.

Контрольная сумма даёт весомое свидетельство только тогда, когда ожидаемый дайджест получен по другому каналу, не связанному с загруженным файлом. Лучший простой вариант - установщик со страницы выпусков поставщика и контрольная сумма в подписанной заметке о выпуске, релизе исходного репозитория или на отдельно поддерживаемой странице безопасности. Хеш рядом с кнопкой загрузки помогает выявить случайное повреждение, но не защищает, если злоумышленник контролирует и страницу, и файл.

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

Для образа диска можно также попросить macOS проверить его внутреннюю структуру:

```sh
hdiutil verify "$HOME/Downloads/VendorSecurity.dmg"
```

Успешная проверка говорит, что структура образа и блоки контрольных сумм внутренне согласованы. Она не устанавливает издателя и не заменяет SHA-256, предоставленную поставщиком.

## Действительная подпись подтверждает целостность, но не качество решения

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

После подключения образа диска или распаковки архива проверьте пакет приложения напрямую. Эта команда проверяет подпись кода и вложенный подписанный код:

```sh
codesign --verify --deep --strict --verbose=4 "/Volumes/Vendor Security/Vendor Security.app"
```

При успехе команда часто почти ничего не выводит. Результатом служит код завершения Terminal, поэтому обычным считается тихий возврат к приглашению. При ошибке `codesign` указывает изменённый файл, недействительную подпись или вложенный компонент, который не прошёл проверку.

Затем выведите сведения о подписи:

```sh
codesign -dvvv "/Volumes/Vendor Security/Vendor Security.app" 2>&1 | \
  egrep "^(Identifier|TeamIdentifier|Authority|Timestamp)="
```

Результат примерно такой:

```text
Identifier=com.vendor.security
TeamIdentifier=ABCDE12345
Authority=Developer ID Application: Vendor, Inc. (ABCDE12345)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=Jan 16, 2026 at 14:32:09
```

Фактическое имя поставщика, идентификатор пакета и Team Identifier должны соответствовать вашим ожиданиям. Запишите Team Identifier. Он гораздо стабильнее и точнее, чем значок или отображаемое имя приложения, и позволяет сравнивать версии при обновлениях.

Не придавайте слову `Authority` лишнего значения. Подпись Developer ID означает, что Apple выдала сертификат зарегистрированному разработчику, а код проходит проверку по этой цепочке. Это не означает, что Apple рекомендует продукт. В документации Apple ясно разделены эти понятия: нотариальное заверение - это автоматическая проверка на вредоносное ПО и корректность подписи, а не App Review.

В рекомендациях Apple по подписи кода также сказано, что разработчикам не следует использовать `codesign --deep` для подписи сложного ПО, поскольку эта команда слишком широко применяет параметры. Это предупреждение относится к созданию подписей. При пользовательской проверке `--deep` полезен, потому что просит `codesign` проверить вложенный код. Но он по-прежнему не анализирует каждый скрипт или файл конфигурации на наличие вредоносного замысла.

Если приложение содержит вспомогательный компонент, инструмент командной строки или расширение, проверка пакета - это первый этап, а не окончательный вывод. В разделе о первом запуске вы сравните эти компоненты с тем, что приложение заявляет о своих потребностях.

## Проверка Gatekeeper оценивает выпуск, который запустит macOS

Выполните проверку Gatekeeper для приложения, даже если подпись выглядит корректной. `spctl` оценивает объект по системной политике, действующей во время запуска. Это ближе к вопросу: «Примет ли этот Mac приложение при обычных настройках защиты?»

Используйте:

```sh
spctl --assess --type execute --verbose=4 \
  "/Volumes/Vendor Security/Vendor Security.app"
```

Обычно результат содержит строки вроде этих:

```text
/Volumes/Vendor Security/Vendor Security.app: accepted
source=Notarized Developer ID
origin=Vendor, Inc. (ABCDE12345)
```

Точная формулировка зависит от версии macOS. Вам нужны принятый объект, источник Notarized Developer ID для прямой загрузки и узнаваемое происхождение.

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

Apple описывает Gatekeeper как механизм, который проверяет загруженное ПО на наличие известного разработчика, нотариального заверения и изменений. Это полезная защита, но всего лишь оценка политики операционной системы. Она должна поддерживать ваше решение, а не заменять оценку издателя и запрашиваемых привилегий.

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

## Прикреплённый билет полезен, но не заменяет всю проверку нотариального заверения

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

Если у вас установлены Xcode Command Line Tools, проверьте наличие прикреплённого билета:

```sh
xcrun stapler validate "/Volumes/Vendor Security/Vendor Security.app"
```

Успешная проверка подтверждает, что билет физически прикреплён к этому пакету. Это удобно для ноутбука, на котором приложение может впервые запускаться без сети.

Не отклоняйте приложение только потому, что команда сообщает об отсутствии прикреплённого билета. Apple указывает, что Gatekeeper может найти билет нотариального заверения онлайн, в том числе если пользователь скачал приложение до завершения заверения. ZIP-архив также не может сам содержать прикреплённый билет. Поставщик должен прикрепить билеты к объектам внутри архива, а затем создать новый архив.

Используйте проверки в таком порядке:

1. Проверьте дайджест SHA-256, если существует независимо опубликованный дайджест.
2. Проверьте подпись приложения и изучите его Team Identifier.
3. Выполните проверку Gatekeeper.
4. Проверьте прикреплённый билет, если инструмент доступен и важен первый запуск без сети.

Оставьте Mac подключённым к сети при первом обычном запуске, если поставщик явно не описал автономную установку. Так Gatekeeper выполнит обычные онлайн-проверки, включая проверку статуса сертификата. Не воспринимайте прикреплённый билет как обещание, что приложение всегда будет приниматься, если его идентичность подписи позже отзовут.

У нотариального заверения есть важные ограничения. Это не полный аудит поведения приложения. Оно не подтверждает безопасность облачного сервиса, надёжность системы обновлений или то, что новая версия запросит только разумные разрешения. Оно говорит, что отправленный файл прошёл автоматический процесс Apple, и даёт Gatekeeper билет для работы.

## Карантин подтверждает происхождение, поэтому не удаляйте его

Расширенный атрибут `com.apple.quarantine` показывает, что macOS получила объект через канал, пометивший его как загруженный или переданный. Он помогает Gatekeeper понять, что это первое событие запуска, которое стоит проверить. Это не метка вредоносного ПО.

Проверьте атрибуты так:

```sh
xattr -l "/Volumes/Vendor Security/Vendor Security.app"
```

Для загруженного объекта можно увидеть примерно такой результат:

```text
com.apple.quarantine: 0083;...;Safari;...
```

Флаги и формат временной отметки относятся к деталям реализации. Важно, что объект сохраняет сведения о происхождении загрузки. Само наличие этого атрибута не делает приложение подозрительным. У большинства загрузок из браузера он есть.

Отсутствие карантина также не делает приложение безопасным. Расширенные атрибуты могут исчезнуть при передаче через архиваторы, сетевые папки, съёмные носители или при копировании коллегой. Apple также указывает, что macOS проверяет ПО на известное вредоносное содержимое при первом открытии независимо от способа его поступления. На практике сохранение происхождения всё же даёт Gatekeeper и вашему процессу проверки больше контекста.

Популярное решение для приложения, которое не открывается, выглядит так:

```sh
xattr -dr com.apple.quarantine "/Applications/Vendor Security.app"
```

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

Управляемый Mac может применять более строгие правила через управление устройствами. В таком случае обход может быть недоступен или запрещён по уважительной причине. Обратитесь к администратору за разрешённым способом установки, вместо того чтобы превращать ограничение в техническую головоломку.

## Пакеты нужно проверять до передачи пароля Installer

`.pkg` заслуживает большего внимания, чем пакет приложения, потому что Installer от Apple после вашего разрешения может записывать данные за пределами пользовательской папки. Продуктам безопасности иногда нужны пакеты для установки привилегированного помощника, системного расширения, сетевого фильтра или вспомогательных компонентов. Это может быть оправданно, но последствия всё равно серьёзны.

Проверьте подпись пакета до двойного нажатия:

```sh
pkgutil --check-signature "$HOME/Downloads/VendorSecurity.pkg"
```

Обычно результат показывает статус подписи пакета, сертификат Developer ID Installer и цепочку сертификатов. Сравните имя поставщика и Team Identifier, если он доступен, с идентичностью, записанной для приложения, или с опубликованными материалами поставщика по установке.

Затем попросите Gatekeeper проверить пакет как установщик:

```sh
spctl --assess --type install --verbose=4 \
  "$HOME/Downloads/VendorSecurity.pkg"
```

Не подменяйте проверку пакета проверкой приложения. Это разные объекты, во многих выпусках подписанные сертификатами разных типов, и последствия их открытия тоже различаются.

До ввода пароля администратора выясните, что именно установщик собирается добавить. Хороший поставщик объясняет, устанавливает ли он привилегированный помощник, системное расширение, элемент входа, профиль конфигурации или сетевой компонент. Расплывчатой формулировки вроде «необходим системный доступ» недостаточно для ПО, которое хочет управлять важными с точки зрения безопасности частями Mac.

Если пакет устанавливает приложение, проверьте установленное приложение до запуска. Подписанный пакет может законно содержать пакет приложения, но подпись пакета не отменяет необходимости проверить подпись исполняемого кода этого приложения.

## Первый запуск - это проверка одобрений, а не гонка за кнопкой Allow

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

Читайте каждое системное сообщение macOS как описание действия, которое хочет выполнить приложение. Обычно запрашиваются уведомления, Full Disk Access, Accessibility, Screen Recording, фильтрация сети, системное расширение или вспомогательный компонент с одобрением администратора. У каждого запроса должна быть конкретная связь с задачей продукта.

Например, приложению для проверки сети может обоснованно понадобиться сетевое расширение. Шлюзу для действий с учётными данными может быть нужно управлять собственным хранилищем и подключаться к указанным сервисам, но для этого ему не нужен универсальный доступ к записи экрана. Сканеру диска может требоваться Full Disk Access, но он должен объяснить, что читает и какие данные остаются локальными. Категория продукта не даёт ему безусловного разрешения.

Используйте эту короткую проверку первого запуска:

- Сопоставьте каждый запрос с документированной функцией, которой вы действительно собираетесь пользоваться.
- Если запрос неожиданен, остановитесь и изучите документацию поставщика до одобрения.
- Не вводите учётные данные администратора, пока не узнаете имя и назначение устанавливаемого компонента.
- После настройки проверьте в System Settings новые Login Items, профили, расширения и фоновые объекты.
- Запишите версию приложения, Team Identifier, хеш загрузки и принятые решения о разрешениях вместе с данными выпуска.

Второй и третий пункты особенно важны, потому что самое дорогостоящее одобрение часто относится не к разрешению приложения. Это компонент, одобренный администратором, который продолжает работать после закрытия окна приложения и может иметь больше доступа, чем само приложение.

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

## Чистая установка не означает безопасную модель работы

Корректная подпись, принятый результат Gatekeeper и разумный набор разрешений - хорошая отправная точка. Но они не доказывают, что приложение будет безопасно действовать после запуска. Нужно также понять, где оно хранит секреты, как проверяет обновления, что отправляет за пределы Mac и сможет ли скомпрометированный процесс злоупотребить своими привилегиями.

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

Именно такой стандарт установки я применяю и к Sallyport: сначала проверяю подписанный выпуск, затем оцениваю его реальные границы. Sallyport хранит учётные данные в зашифрованном хранилище и сам выполняет одобренные действия через HTTP или SSH, не передавая секреты процессу агента.

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