Этот урок - про механику. Не "где галочка в настройках", а как устроено хранилище, что реально шифруется, кто и когда тебя спросит пароль, и где разложены грабли.
Что такое связка ключей и зачем она нужна
Связка ключей (Keychain) - это зашифрованная база, где macOS хранит пароли mac, ключи, сертификаты, секретные заметки и токены. Физически это файл-контейнер, а API поверх него (Security.framework) умеет шифровать каждый элемент, навешивать списки доступа (ACL) и спрашивать разрешение, прежде чем отдать секрет приложению.
Ключевой принцип: секрет в связке ключей зашифрован, и расшифровать его можно только при разблокированной связке. А разблокируется она мастер-паролем. Для главной, login-связки этот мастер-пароль по умолчанию равен паролю твоей учётной записи - поэтому при входе в систему она открывается автоматически. Это удобно и это же ловушка: если злоумышленник знает пароль входа, он открывает всю login-связку.
На одной машине связок несколько, и это не дубликаты, а слои с разной зоной ответственности:
- login keychain - твоя личная связка, файл ~/Library/Keychains/login.keychain-db. Пароли сайтов, токены, заметки. Разблокируется паролем входа.
- System keychain - /Library/Keychains/System.keychain. Общесистемное: пароли Wi-Fi, сертификаты доверенных центров, машинные ключи. Доступ - через root, элементы видны всем пользователям машины.
- iCloud Keychain - синхронизируемая через iCloud связка (внутри представлена как com.apple.security.cloudkeychainproxy3 / "Local Items"). Пароли, passkey, коды двухфакторки уезжают на все твои устройства с одним Apple ID, сквозное шифрование.
- System Roots - read-only связка корневых сертификатов Apple в /System/Library/Keychains. Её ты не редактируешь.
Старый GUI Keychain Access (Связка ключей, /System/Applications/Utilities/Keychain Access.app) никуда не делся и остаётся главным инструментом для сертификатов, системной связки и низкоуровневой возни с ACL - того, что новое приложение Пароли не показывает.

security: связка ключей из терминала
Весь CLI - это одна утилита security cli mac. Подкоманд десятки, посмотри список:
Код: Выделить всё
security help
security help add-generic-password
Добавим секрет - например, токен доступа:
Код: Выделить всё
security add-generic-password -s "github-token" -a "$USER" -w "ghp_xxxxYYYYzzz" -U
Достаём секрет обратно:
Код: Выделить всё
security find-generic-password -s "github-token" -a "$USER" -w
Код: Выделить всё
keychain: "/Users/dev/Library/Keychains/login.keychain-db"
class: "genp"
attributes:
"acct"<blob>="dev"
"svce"<blob>="github-token"
"mdat"<timedate>=0x32303236... "20260615101533Z\000"
0x00000007 <blob>="github-token"
Код: Выделить всё
TOKEN=$(security find-generic-password -s "github-token" -a "$USER" -w)
curl -H "Authorization: Bearer $TOKEN" https://api.github.com/user
Удаление и поиск интернет-пароля:
Код: Выделить всё
security delete-generic-password -s "github-token" -a "$USER"
security find-internet-password -s "example.com" -r "htps" -w
Управление самой связкой:
Код: Выделить всё
security list-keychains
security default-keychain
security lock-keychain
security unlock-keychain
security set-keychain-settings -t 3600 -l ~/Library/Keychains/login.keychain-db
ACL, Touch ID и доступ приложений
Самое непонятное в связке - почему иногда выскакивает "приложение хочет получить доступ к связке ключей, введите пароль", а иногда нет. Отвечает за это ACL (список контроля доступа) у каждого элемента. В ACL записано, какие приложения имеют право читать секрет без запроса пароля.
Когда ты создаёшь элемент через security без -T, доверенным становится сам бинарь security - то есть скрипты будут читать без вопросов, а вот Safari или другое приложение спросит. Флаг -T задаёт конкретное приложение, которому разрешено:
Код: Выделить всё
security add-generic-password -s "db-prod" -a "app" -w 'S3cr3t' \
-T /usr/bin/security -T /opt/homebrew/bin/myapp
Теперь про Touch ID. Важно честно понимать границу: штатная утилита security НЕ умеет защищать элемент биометрией. Touch ID к связке прикручивается только через программный API (LocalAuthentication, kSecAccessControlTouchIDAny) - это про приложения, которые сами кладут секрет в Secure Enclave и требуют отпечаток на чтение. Из коробки в CLI этого нет, и если видишь сторонние утилиты "Touch ID for keychain" - они написаны как раз поверх этого API, а не поверх флагов security. Не выдумывай несуществующий security --touchid, его нет.
Зато Touch ID реально работает для разблокировки самой связки и для sudo. А секреты внутри защищены в первую очередь шифрованием связки и её ACL.
Сертификаты, доверие и passkey
Связка ключей хранит не только пароли, но и сертификаты с приватными ключами. Типичный сценарий разработчика - локальный самоподписанный CA для dev-окружения. Импорт и просмотр:
Код: Выделить всё
security import dev-ca.p12 -k ~/Library/Keychains/login.keychain-db -P 'passphrase'
security find-certificate -a -c "My Dev CA" -p
security export -t certs -f pemseq -o all-certs.pem
Код: Выделить всё
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain dev-ca.pem
Passkey (passkey, беспарольная аутентификация) - это асимметричная пара ключей вместо пароля. Приватный ключ не покидает устройство (точнее, синхронизируется только через сквозь-зашифрованную iCloud Keychain), на сервер уходит лишь публичный, а вход подтверждается биометрией - Touch ID или Face ID. Фишинг по passkey невозможен в принципе: ключ привязан к домену, поддельный сайт не получит подпись. В Tahoe passkey живут в приложении Пароли и требуют включённой iCloud Keychain - без неё локально на Mac их не создать. Управляешь ими через приложение Пароли (Пароли -> выбрать запись -> там же passkey и коды подтверждения), а не через security - CLI passkey не редактирует.
Типичные грабли
- Пароль секрета в командной строке через -w 'mysecret' уходит в историю shell. Опускай -w и вводи интерактивно, либо чисти историю.
- После смены пароля учётки login-связка может остаться со старым мастер-паролем и сыпать запросами. Лечится в GUI: Связка ключей -> Правка -> Сменить пароль для связки, либо security set-keychain-password.
- find-generic-password без -w печатает метаданные, но не пароль. Забыл -w - решил, что секрета нет. Он есть.
- Путаешь login и iCloud-связку. Элементы из "Local Items"/iCloud не лежат в login.keychain-db, security их видит ограниченно - управляй ими через приложение Пароли.
- Ждёшь, что security защитит секрет по Touch ID. Не защитит - это API-история, а не флаг CLI.
- add-trusted-cert в скрипте "молча" больше не сработает на свежих macOS - готовь профиль/MDM для парка.
Повтори руками, 10 минут:
- Создай секрет: security add-generic-password -s "lab-secret" -a "$USER" -U и введи значение интерактивно (без -w).
- Прочитай метаданные без -w, затем с -w. Сравни вывод.
- Подставь секрет в команду: echo "Secret is: $(security find-generic-password -s lab-secret -a "$USER" -w)".
- Заблокируй связку: security lock-keychain, снова прочитай секрет - получи запрос пароля. Разблокируй: security unlock-keychain.
- Открой Связку ключей.app, найди lab-secret, посмотри вкладку Контроль доступа.
- Удали: security delete-generic-password -s "lab-secret" -a "$USER".
- Чем login keychain отличается от System keychain по расположению файла и по тому, кто его разблокирует?
- Зачем при чтении секрета через find-generic-password нужен флаг -w и что выводится без него?
- Почему security сам по себе не умеет защищать элемент по Touch ID и где биометрия к связке всё же подключается?
- Что требуется для создания passkey на Mac в Tahoe и почему passkey устойчив к фишингу?
Связка ключей - штатное шифрованное хранилище секретов macOS, а security - твой ключ к нему из терминала. Держи токены и ключи разработки в login-связке и тяни их в скрипты через find-generic-password -w вместо хардкода в открытых файлах. Понимай слои: login (личное), System (машинное, root), iCloud (синхронизация, passkey, приложение Пароли). Помни границы CLI: Touch ID и passkey живут в API и приложении Пароли, а не во флагах security, а бесшумная установка доверенных сертификатов на парк - через MDM. Этого хватит, чтобы перестать раскидывать секреты по .env и навести порядок в хранилище.
Источники: ss64.com/mac/security.html, support.apple.com/guide/passwords, support.apple.com/guide/keychain-access, support.apple.com/guide/deployment, developer.apple.com.