# Секреты и авторизация REST API Crank может вызывать REST API без авторизации или с авторизацией через сохраненный секрет. ## Администратор и browser sessions Первый production-admin не создаётся из static startup password. Оператор создаёт локальный bootstrap-контракт командой: ```bash crank-migrate admin-auth bootstrap-create --email owner@example.local ``` Команда выводит одноразовый token. Token вводится на `/login` вместе с первым паролем; повторное использование или истёкший token отклоняется одинаковой ошибкой без раскрытия причины. После login сервер устанавливает HttpOnly session cookie и возвращает `csrf_token`. Все unsafe browser mutations под `/api/auth/*` и `/api/admin/*` требуют `x-csrf-token`; cross-origin `/api/*` requests отклоняются по умолчанию. Смена пароля отзывает активные browser sessions и CSRF state. Если Admin password потерян, оператор выполняет recovery локально. Команда проверяет active master-key identity, заменяет verifier существующего Admin account и отзывает все browser sessions; старый пароль, Secrets и key material не раскрываются: ```bash crank-migrate admin-auth recover \ --email owner@example.local \ --password-file /secure/new-admin-password.txt \ --password-pepper-file /secure/password-pepper.txt \ --master-key-file /secure/current-master.key ``` ## Секреты Поддерживаемые типы: - токен; - логин и пароль; - значение HTTP-заголовка; - произвольный JSON. Секреты шифруются ключом `CRANK_MASTER_KEY`. Значение должно быть не короче 32 bytes; слабый или пустой ключ отклоняется до product readiness. После создания или ротации значение секрета нельзя прочитать через UI или API. PostgreSQL хранит только encrypted secret value, `key_version` и master-key epoch. Сам `CRANK_MASTER_KEY`, derived key bytes и plaintext Secret не сохраняются и не выводятся в diagnostics. ## Master-key identity и rotation После миграции schema до текущей версии первый secret-using process регистрирует в PostgreSQL non-secret identity активного master key: - epoch; - fingerprint; - cipher contract. `admin-api` и `mcp-server` проверяют эту identity до product readiness. Если process запускается на populated database без identity, он сначала доказывает, что текущий key расшифровывает все существующие Secret versions, и только затем регистрирует fingerprint. Если процесс запущен с другим `CRANK_MASTER_KEY`, startup завершается безопасной ошибкой `master_key_identity_mismatch`; сохранённые Secrets при этом не перезаписываются. Ротация master key выполняется только локальной операторской командой `crank-migrate master-key ...`. Ключевой материал передаётся через локальные файлы, а не через аргументы со значениями: ```bash crank-migrate master-key preflight \ --current-key-file /secure/current.key \ --target-key-file /secure/target.key \ --backup-ref offline-backup-ref crank-migrate master-key rotate \ --current-key-file /secure/current.key \ --target-key-file /secure/target.key \ --backup-ref offline-backup-ref crank-migrate master-key verify --target-key-file /secure/target.key crank-migrate master-key promote --target-key-file /secure/target.key ``` `preflight` read-only: проверяет текущий ключ, decryptability существующих Secret versions, уникальность target fingerprint и отсутствие активной rotation. `rotate` создаёт durable rotation record и target ciphertext, не удаляя текущий ciphertext. Если команда прерывается, повторный `rotate` продолжает обработку по сохранённому checkpoint. `verify` должен успешно расшифровать все target ciphertext до `promote`. До promotion новые create/rotate Secret writes fail-closed с `master_key_rotation_in_progress`. После `promote` активный epoch меняется атомарно; процессы должны быть перезапущены с target key. Старый key после этого не проходит readiness. Если ошибка возникла до promotion: ```bash crank-migrate master-key abort --rotation-id master-key-e1-to-e2 ``` Abort оставляет текущий epoch активным и очищает staged target ciphertext. `backup_ref` — только opaque ссылка на внешний защищённый backup; Crank не хранит key bytes в product backup set. ## Профили авторизации Профиль авторизации описывает, как применить секрет к REST-запросу: - `Bearer token`; - `Basic auth`; - API key в заголовке; - API key в query-параметре. Операция хранит ссылку на профиль авторизации, а не само значение секрета. ## Рекомендации - Не вставляйте токены в статические заголовки операции. - Используйте секреты и профили авторизации для всех чувствительных данных. - Ротируйте секрет при подозрении на утечку. - Ротируйте `CRANK_MASTER_KEY` только через `crank-migrate master-key`; не меняйте значение в `.env` без preflight/rotate/verify/promote. - Не экспортируйте реальные секреты вместе с YAML-конфигурациями.