Runbook — Ротация секретов
Техническое руководство из исходного проекта Notty. Примеры, параметры и эксплуатационные ограничения.
Когда: плановая (по cadence из secrets-management.md)
или внеплановая (подозрение на утечку, увольнение оператора с доступом, аудит).
Общая последовательность
- Сгенерировать новый секрет (вне prod-машины).
- Записать в secret backend (Vault/SM/External Secrets/k8s Secret).
- Применить в runtime через rolling update.
- Подтвердить, что Notty работает с новым секретом.
- Отозвать/удалить старое значение в backend.
- Отметить ротацию в журнале операций.
JWT_SECRET
Эффект: все активные admin-сессии и JWT-токены становятся невалидны. Всем пользователям нужно перелогиниться. API tokens (хранятся в БД) не страдают.
# 1. Сгенерировать новый секрет (никуда не выводя в shell history дольше нужного)
NEW_JWT="$(openssl rand -base64 64 | tr -d '\n')"
# 2a. Kubernetes — рекомендуемый путь: положить новый JWT_SECRET в secret backend
# (Vault / AWS SM / GCP SM); ESO синхронизирует его в `notty-secrets`.
# Затем — rolling restart:
kubectl -n notty rollout restart deploy/notty
kubectl -n notty rollout status deploy/notty --timeout=180s
# Если backend'а нет, патч точечно — JWT_SECRET в base64:
NEW_JWT_B64=$(printf '%s' "$NEW_JWT" | base64 | tr -d '\n')
kubectl -n notty patch secret notty-secrets --type=merge \
-p "{\"data\":{\"JWT_SECRET\":\"$NEW_JWT_B64\",\"NITRO_JWT_SECRET\":\"$NEW_JWT_B64\"}}"
kubectl -n notty rollout restart deploy/notty
kubectl -n notty rollout status deploy/notty --timeout=180s
# 2b. docker-compose — через готовый скрипт
./deployment/scripts/secret-rotate-jwt.sh --rotate \
--file .env --reload-compose notty
Подтверждение:
verify-deploy.shзелёный;- логин в admin UI работает (после ре-ввода паролей).
DATABASE_URL (пароль БД)
Эффект: при rolling update'е каждый pod на старте откроет новый коннект. Активные сессии БД на старом пароле останутся живыми до перезапуска pod'а.
- В managed PG: создать новый пароль или временно второго пользователя с тем же набором прав.
- Обновить
DATABASE_URLв secret backend. kubectl rollout restart deploy/notty(илиdocker compose up -d --no-deps notty).- Дождаться
rollout statusи/api/readyz. - Удалить старый пароль/пользователя в managed PG.
STORAGE_ACCESS_KEY_ID / STORAGE_SECRET_ACCESS_KEY
S3 / R2 / совместимые позволяют иметь несколько активных ключей.
- Создать новый access key в облаке. Старый пока оставить.
- Обновить secret backend.
- Rolling restart Notty.
- Проверить, что media upload и доступ работают (загрузить тестовый файл).
- Удалить старый access key.
OAuth client secret
- Сгенерировать новый client secret в провайдере (Google/GitHub/VK/Facebook).
- Обновить
*_CLIENT_SECRETв secret backend. - Rolling restart.
- Проверить полный OAuth-флоу (login через провайдер).
- Удалить старый secret в провайдере.
API tokens (в БД)
Используйте админ-API:
# Список
curl -H "Authorization: Bearer $ADMIN_TOKEN" $BASE/api/admin/api-tokens
# Revoke
curl -X DELETE -H "Authorization: Bearer $ADMIN_TOKEN" \
$BASE/api/admin/api-tokens/<id>
# Создать новый
curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"ci-runner","scopes":["content:read"]}' \
$BASE/api/admin/api-tokens
Передайте новый токен потребителю out-of-band; не вешайте в логах.
Webhook signing keys
При компрометации:
- Через UI/API regenerate signing key конкретного webhook'а.
- Сообщить получателю новый ключ out-of-band.
- Получатель должен в течение N минут обновить верификацию подписи.
- Замониторить
dead-letter(/api/webhooks/dead-letter) — если получатель не успел переключиться, реплейните после.
Чек-лист после любой ротации
- Smoke зелёный.
- Логи без всплеска auth/db ошибок.
-
notty_http_request_errors_totalстабилен. - Запись в operations log: дата, кто ротировал, какой секрет, причина.
- Старое значение удалено в backend и в провайдере.
Источник: docs/operations/runbooks/secret-rotation.md. Снимок документации исходного проекта. Технический справочник сохраняет язык оригинала.