Приватность и TCC: разрешения на доступ

Рейтинг: 56.5% · 9 голосов
Подробный курс по macOS для разработчиков и админов: архитектура и Apple Silicon, терминал и zsh, Homebrew и пакеты, launchd и автоматизация, APFS и Time Machine, безопасность (SIP, Gatekeeper, TCC, FileVault), сеть, логи и диагностика, MDM и DDM, контейнеры и виртуализация, восстановление. По официальной документации Apple, актуально на 2026 (macOS 26 Tahoe).
Ответить
Аватара пользователя
Artem_MacAdmin
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Приватность и TCC: разрешения на доступ

Сообщение Artem_MacAdmin »

Оглавление курса (47)
  1. Что такое macOS: Unix под капотом и место в 2026
  2. Архитектура macOS: XNU, тома и Signed System Volume
  3. Apple Silicon: ARM, Rosetta 2 и отличия от Intel
  4. Установка, обновление и восстановление macOS
  5. Finder, рабочий стол и продуктивность
  6. Системные настройки и их управление из CLI (defaults)
  7. Пользователи и группы: учётные записи и управление
  8. Терминал и zsh: командная строка macOS
  9. CLI на macOS: BSD-команды и отличия от Linux
  10. Настройка zsh: .zshrc, prompt, плагины
  11. Файловая система и права: POSIX, ACL, атрибуты, флаги
  12. Homebrew: пакетный менеджер для macOS
  13. Homebrew глубже: tap, Brewfile, services, обслуживание
  14. Другие пакеты: MacPorts, mas, Nix и App Store
  15. Установка приложений: .app, .dmg, .pkg и Gatekeeper
  16. Управление приложениями и их данные
  17. launchd и launchctl: система запуска macOS
  18. Свои службы и периодические задачи на launchd
  19. Автоматизация: Shortcuts, AppleScript и osascript
  20. Конфигурация как код: defaults, plist и профили
  21. APFS: снапшоты, клоны, контейнеры и шифрование
  22. Управление дисками: diskutil, образы и форматирование
  23. Time Machine и резервное копирование
  24. Внешние диски, форматы и сетевые тома
  25. Модель безопасности macOS: SIP и целостность системы
  26. Gatekeeper, нотаризация и защита от вредоносов
  27. Приватность и TCC: разрешения на доступ (вы здесь)
  28. FileVault: полнодисковое шифрование
  29. Связка ключей и управление секретами
  30. Сетевой экран и защита сети
  31. Сеть в macOS: настройка и инструменты
  32. Диагностика сети на Mac
  33. Общий доступ: SSH, экран, файлы, удалённое управление
  34. Процессы и ресурсы: мониторинг производительности
  35. Логи macOS: unified logging и диагностика
  36. Производительность и энергия: powermetrics, диагностика
  37. Энергия, сон и обслуживание системы
  38. Профили конфигурации и основы MDM
  39. Управление парком Mac: MDM, DDM и zero-touch (2026)
  40. Среда разработчика на Mac: Xcode CLT, git, версии
  41. Контейнеры на Mac: Docker Desktop, OrbStack, Apple container
  42. Виртуализация: Virtualization.framework, UTM, Linux и Windows
  43. Режимы загрузки и восстановление (Apple Silicon)
  44. Сброс, NVRAM, Safe Mode и сброс настроек
  45. Траблшутинг macOS: дерево решений по симптомам
  46. Место на диске и обслуживание системы
  47. Сквозной проект: настройка Mac как у профи + куда расти
Ты пишешь баш-скрипт, который должен пройтись по чужому Рабочему столу и собрать отчёт. Запускаешь из Терминала - и получаешь "Operation not permitted" на ровном месте, хотя ты под админом и даже под sudo. Или: настроил автоматизацию, которая дёргает Системные события, ночью по расписанию вылезает диалог "Терминал хочет управлять System Events", никто на него не жмёт, и весь пайплайн встаёт. Знакомо? За всем этим стоит TCC - подсистема приватности macOS. Разберём её механику до винтиков: что она защищает, где живёт база, как сбрасывать разрешения, почему скриптам нужен Full Disk Access и как не отстрелить себе ногу в автоматизации.

Что такое TCC и зачем он вообще

TCC - это Transparency, Consent and Control (прозрачность, согласие и контроль). Идея простая: ни одно приложение не должно молча лезть к твоей камере, микрофону, контактам или личным файлам. Когда программа впервые пытается дотянуться до защищённого ресурса, система перехватывает запрос и показывает тот самый диалог "Приложение X запрашивает доступ к ...". Твоё решение (разрешить/запретить) сохраняется, и больше система не спрашивает - пока ты сам не сбросишь.

Это центральный кусок модели конфиденциальности macOS (privacy mac). Управляется демоном tccd: один работает на уровне системы, другой - в твоём пользовательском сеансе. Когда процесс делает системный вызов к защищённому API, ядро и фреймворки спрашивают у tccd: "этому бинарю можно?". tccd смотрит в свою базу и либо пускает, либо инициирует диалог согласия, либо режет молча (если профилем задан запрет).

Что именно охраняет TCC mac:
  • Камера и Микрофон - доступ к захвату видео/звука;
  • Геолокация (Службы геолокации) - где находится Mac;
  • Контакты, Календари, Напоминания - персональные данные из системных приложений;
  • Фото - доступ к медиатеке Фото;
  • Запись экрана (Screen Recording) - снимать экран и окна других программ;
  • Универсальный доступ (Accessibility) - программно управлять интерфейсом: жать кнопки, двигать мышь, читать содержимое окон;
  • Полный доступ к диску (Full Disk Access) - читать защищённые зоны: Почту, Сообщения, историю Safari, чужие ~/Library, базы самого TCC;
  • Папки Документы, Рабочий стол, Загрузки - так называемый pop-up на пользовательские папки;
  • Автоматизация (Automation) - управлять другими приложениями через Apple Events (AppleScript, osascript).
Изображение

Где это лежит: база TCC.db и две зоны ответственности

Все решения хранятся в SQLite-базах. Их две, и это принципиально:

Код: Выделить всё

~/Library/Application Support/com.apple.TCC/TCC.db   # пользовательская
/Library/Application Support/com.apple.TCC/TCC.db    # системная
Пользовательская держит разрешения на камеру, микрофон, контакты, Automation - то, что касается данных конкретного юзера. Системная (под защитой SIP) держит то, что действует на всю машину: Accessibility, Full Disk Access (внутри она зовётся SystemPolicyAllFiles), Screen Recording.

Залезть туда напрямую через sqlite3 не выйдет, даже под root, если у твоего терминала нет Full Disk Access - сама база TCC защищена TCC, такая вот рекурсия. Глянуть структуру можно, когда доступ есть:

Код: Выделить всё

$ sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" \
  "SELECT service, client, auth_value FROM access LIMIT 5;"
kTCCServiceSystemPolicyAllFiles|com.apple.Terminal|2
kTCCServiceScreenCapture|us.zoom.xos|2
kTCCServiceAccessibility|com.googlecode.iterm2|2
Разбор: service - внутреннее имя ресурса (с префиксом kTCCService), client - бандл-идентификатор приложения, auth_value - решение: 0 запрещено, 2 разрешено, 3 ограничено/нужен повторный запрос. Видишь, что Terminal имеет SystemPolicyAllFiles со значением 2 - это и есть Full Disk Access, выданный вручную.

Важно: не правь TCC.db руками через sqlite3 в проде. Apple это явно не поддерживает, формат меняется между релизами, а на системной базе SIP всё равно не даст записать. Для управления есть штатные инструменты - tccutil и профили.

Управление через GUI и сброс через tccutil

Глазами всё это живёт в Системные настройки -> Конфиденциальность и безопасность (в macOS 26 Tahoe это System Settings, не старые Preferences). Там список категорий, в каждой - тумблеры по приложениям. Это основное место, где обычный человек раздаёт разрешения mac.

Но рулить мышкой - не наш метод. Из терминала есть tccutil. У него по сути одна боевая команда - reset, она стирает уже принятое решение, чтобы система спросила заново при следующем обращении. Сам выдать разрешение tccutil НЕ может (это by design - иначе грош цена согласию пользователя).

Синтаксис: tccutil reset <Сервис> [bundle_id]. Имена сервисов чувствительны к регистру и идут без префикса kTCCService.

Код: Выделить всё

# сбросить Accessibility для всех приложений
$ sudo tccutil reset Accessibility

# сбросить только запись экрана для Zoom
$ sudo tccutil reset ScreenCapture us.zoom.xos

# сбросить Full Disk Access для конкретного приложения
$ sudo tccutil reset SystemPolicyAllFiles com.microsoft.VSCode

# снести вообще все решения для одного приложения
$ tccutil reset All com.apple.Terminal

# ядерный вариант - сбросить всё и для всех (не делай так на рабочей машине)
$ sudo tccutil reset All
Полезные имена сервисов: Camera, Microphone, ScreenCapture, Accessibility, SystemPolicyAllFiles, AddressBook (контакты), Photos, Calendar, Reminders, AppleEvents (Automation), ListenEvent. Полный перечень Apple не документирует, и он меняется со временем.

Типичный сценарий: приложение глючит с разрешениями, диалог не появляется или ты случайно нажал "Запретить". Лечится так:

Код: Выделить всё

$ killall "Google Chrome"               # сначала прибить процесс
$ tccutil reset Camera com.google.Chrome
$ tccutil reset Microphone com.google.Chrome
Прибить процесс перед сбросом критично: tccd кеширует решения в памяти живого процесса, и пока приложение не перезапустится, сброс может не подхватиться.

Почему скрипты и Терминал требуют Full Disk Access

Вот корень самой частой боли. Ты под sudo, ты root, но cat чужого ~/Library/Mail падает с "Operation not permitted". POSIX-права тут ни при чём - root по ним всё может. Режет именно TCC: чтение защищённых зон требует Full Disk Access, и проверка идёт не по UID, а по тому, КАКОЙ бинарь инициировал доступ.

А инициатор - это твой Терминал (или iTerm2, или VS Code, из которого ты запускаешь скрипт). Скрипт сам по себе не имеет идентичности в глазах TCC; он наследует права хост-приложения. Поэтому Full Disk Access выдаётся не скрипту, а Терминалу: Системные настройки -> Конфиденциальность и безопасность -> Полный доступ к диску -> добавить Терминал, тумблер включить. После этого любой скрипт, запущенный из этого Терминала, видит защищённые файлы.

Проверить на пальцах:

Код: Выделить всё

$ ls ~/Library/Mail
ls: : Operation not permitted     # FDA нет
# ... выдаём Терминалу Full Disk Access, перезапускаем его ...
$ ls ~/Library/Mail
V10  V11                          # теперь видно
Никакого sudo здесь не нужно - решает наличие FDA у приложения-хоста, а не суперпользователь. Это и есть ответ на вопрос "почему full disk access вообще существует": защитить личные данные даже от локального админа и от скриптов, которые он запускает не глядя.

Грабли автоматизации: launchd + TCC

Самое больное место - фоновые задачи. Ты делаешь LaunchAgent/LaunchDaemon (launchd, не cron - в macOS планировщик это launchd), который по расписанию скриншотит экран или дёргает другое приложение через osascript. И оно не работает, причём молча.

Почему. TCC-диалог согласия требует пользовательского интерфейса и интерактивной сессии. У LaunchDaemon её нет вообще (он в системном контексте, до логина). У LaunchAgent она есть, но если задача стрельнула, когда никто не смотрит на экран, диалог либо не покажется, либо провисит и отвалится по таймауту. Результат - доступ не выдан, задача упала.

Второй слой граблей - наследование идентичности. Когда launchd запускает /bin/zsh твой скрипт, TCC-клиентом считается процесс, который реально вызывает защищённый API. Для Apple Events это будет интерпретатор (osascript), и согласие на Automation привяжется к нему, а не к Терминалу. Поэтому разрешение, выданное вручную в интерактивной сессии, может не подхватиться в фоне - другой клиент, другая запись в базе.

Что делать на практике:
  • Выдай нужные разрешения заранее, в интерактивной сессии, тому самому бинарю, который потом будет работать в фоне (например, прогони osascript из Терминала один раз, прими диалог Automation).
  • Для парка машин - не надейся на диалоги вообще, раздавай разрешения профилем PPPC (см. ниже). Диалог в фоне ловить бесполезно.
  • Запускай агент в правильном контексте: задаче с GUI нужен LaunchAgent в сессии залогиненного юзера (gui/<uid>), а не LaunchDaemon.
  • Помни: AppleEvents/Automation чаще всего и есть та категория, которую душит фон. Проверяй журнал.
Диагностика через унифицированный лог (log, не /var/log):

Код: Выделить всё

$ log stream --predicate 'subsystem == "com.apple.TCC"' --info
# дёрни задачу в другом окне и читай, что решает tccd:
... tccd: REQUESTING kTCCServiceAppleEvents from osascript
... tccd: Prompting policy for ... DENIED (no interactive session)
Строка DENIED no interactive session прямо говорит: фон, диалог некому показать. Лечится предварительной выдачей или профилем.

Профили PPPC для парка и роль подписи

В компании раздавать разрешения по машинам руками - тупик. Для этого есть PPPC - Privacy Preferences Policy Control. Это конфигурационный профиль (тип payload com.apple.TCC.configuration-profile-policy), который через MDM прилетает на устройство и заранее проставляет в системной TCC-базе нужные решения. Никаких диалогов - всё уже решено политикой. В 2026 это часть стандарта Declarative Device Management (DDM).

Ключевой момент про идентичность: профиль PPPC привязывает разрешение не к имени приложения, а к его подписи. В payload указываются bundle identifier и code requirement - криптографическое требование к подписи бинаря. Поэтому подпись и TCC связаны намертво: если приложение пересобрали с другим сертификатом или сломали подпись, code requirement перестаёт совпадать и профиль молча не сработает.

Получить code requirement для своего инструмента:

Код: Выделить всё

$ codesign -dr - /Applications/MyAgent.app
designated => identifier "com.acme.MyAgent" and anchor apple generic and \
  certificate leaf[subject.OU] = "ABCDE12345"
Вот эту строку (после designated =>) и кладут в поле CodeRequirement профиля. Свежий нюанс 2026: до macOS 26 Tahoe разрешения, выданные через MDM/PPPC, вообще не отображались в Конфиденциальности и безопасности - админ не видел, что профиль реально применился. Начиная с Tahoe 26.2 эти настройки наконец видны в System Settings, отлаживать парк стало легче.

Чего PPPC НЕ умеет: профилем нельзя ВЫДАТЬ доступ к Камере, Микрофону и Записи экрана. По этим трём категориям MDM может только запретить или оставить решение пользователю - финальное "да" всё равно жмёт человек. Зато Accessibility, Full Disk Access (SystemPolicyAllFiles) и Apple Events профиль раздаёт полноценно, без участия юзера, что и закрывает боль фоновой автоматизации в парке.

Мини-лаба: пощупать TCC руками

Делай на личной тестовой машине, не на проде.
  • 1. Без Full Disk Access у Терминала выполни ls ~/Library/Mail и поймай Operation not permitted.
  • 2. Системные настройки -> Конфиденциальность и безопасность -> Полный доступ к диску -> добавь Терминал, включи тумблер, полностью перезапусти Терминал (Cmd+Q). Повтори ls - теперь видно.
  • 3. Узнай бандл-ид своего браузера: osascript -e 'id of app "Safari"'.
  • 4. Запусти log stream --predicate 'subsystem == "com.apple.TCC"' --info в одном окне, в другом - osascript -e 'tell app "Finder" to get name of every window'. Прими диалог Automation и найди в логе строку REQUESTING kTCCServiceAppleEvents.
  • 5. Сбрось это решение: tccutil reset AppleEvents и убедись, что при следующем запуске диалог появился снова.
Контрольные вопросы
  • 1. Почему скрипт, запущенный под sudo, всё равно не может прочитать чужую ~/Library/Mail, и кому в итоге выдаётся Full Disk Access?
  • 2. Чем системная TCC.db отличается от пользовательской, и какие категории живут в каждой?
  • 3. Что делает tccutil reset ScreenCapture us.zoom.xos, и почему перед сбросом приложение надо прибить через killall?
  • 4. Почему фоновая launchd-задача с Apple Events часто молча падает, и как это лечится в парке через PPPC?
Итог

TCC - это не каприз, а сознательный барьер: согласие пользователя на доступ к камере, файлам и управлению другими приложениями стоит выше прав root. Запомни три вещи. Первое: защищённые файлы открывает не sudo, а Full Disk Access у приложения-хоста твоего скрипта. Второе: в фоне диалоги не работают - либо выдавай разрешения заранее тому же бинарю, либо раздавай профилем PPPC. Третье: PPPC держится на подписи приложения через code requirement, и Камеру с Микрофоном профилем не выдашь. Держи под рукой tccutil reset для отладки и log stream по subsystem com.apple.TCC, когда что-то режется молча.
👍2 ❤️2 🔥 😄 🤔
Аватара пользователя
joe13
Сообщения: 1
Зарегистрирован: 18 май 2026, 00:23

Re: Приватность и TCC: разрешения на доступ

Сообщение joe13 »

Вот оно что. Месяц воевал с ночным скриптом скриншотов через launchd - падал молча, а это TCC резал Apple Events в фоне. log stream по subsystem com.apple.TCC сразу показал DENIED no interactive session. Спасибо, выдал разрешение заранее из Терминала и всё поехало.
👍1 ❤️ 🔥 😄 🤔1
Аватара пользователя
mother22
Сообщения: 1
Зарегистрирован: 24 май 2026, 14:55

Re: Приватность и TCC: разрешения на доступ

Сообщение mother22 »

Уточните - если приложение обновилось и подпись слегка поменялась, профиль PPPC отвалится? У нас VS Code сам себя апдейтит, боюсь что FDA по code requirement слетит после очередной версии.
👍3 ❤️1 🔥 😄 🤔
Ответить
← Предыдущая глава
Gatekeeper, нотаризация и защита от вредоносов
Следующая глава →
FileVault: полнодисковое шифрование

Все главы курса «macOS для профи: администрирование, терминал и Homebrew»

Поделиться темой: ✈ Telegram VK
Похожие запросы: Настройка сети на MacБезопасность macOS

Вернуться в «macOS для профи: администрирование, терминал и Homebrew»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя