Files
crank/docs/secrets-and-auth.md
T

6.5 KiB
Raw Blame History

Секреты и авторизация REST API

Crank может вызывать REST API без авторизации или с авторизацией через сохраненный секрет.

Администратор и browser sessions

Первый production-admin не создаётся из static startup password. Оператор создаёт локальный bootstrap-контракт командой:

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 не раскрываются:

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 .... Ключевой материал передаётся через локальные файлы, а не через аргументы со значениями:

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:

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-конфигурациями.